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

Unified Diff: net/proxy/single_threaded_proxy_resolver_unittest.cc

Issue 2822043: Add the capability to run multiple proxy PAC scripts in parallel.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Re-upload after revert Created 10 years, 5 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 | « net/proxy/single_threaded_proxy_resolver.cc ('k') | net/proxy/sync_host_resolver_bridge.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/proxy/single_threaded_proxy_resolver_unittest.cc
===================================================================
--- net/proxy/single_threaded_proxy_resolver_unittest.cc (revision 51914)
+++ net/proxy/single_threaded_proxy_resolver_unittest.cc (working copy)
@@ -1,476 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/string_util.h"
-#include "base/waitable_event.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/net_log.h"
-#include "net/base/net_log_unittest.h"
-#include "net/base/net_errors.h"
-#include "net/base/test_completion_callback.h"
-#include "net/proxy/proxy_info.h"
-#include "net/proxy/single_threaded_proxy_resolver.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace {
-
-// A synchronous mock ProxyResolver implementation, which can be used in
-// conjunction with SingleThreadedProxyResolver.
-// - returns a single-item proxy list with the query's host.
-class MockProxyResolver : public ProxyResolver {
- public:
- MockProxyResolver()
- : ProxyResolver(true /*expects_pac_bytes*/),
- wrong_loop_(MessageLoop::current()),
- request_count_(0),
- purge_count_(0),
- resolve_latency_ms_(0) {}
-
- // ProxyResolver implementation:
- virtual int GetProxyForURL(const GURL& query_url,
- ProxyInfo* results,
- CompletionCallback* callback,
- RequestHandle* request,
- const BoundNetLog& net_log) {
- if (resolve_latency_ms_)
- PlatformThread::Sleep(resolve_latency_ms_);
-
- CheckIsOnWorkerThread();
-
- EXPECT_TRUE(callback == NULL);
- EXPECT_TRUE(request == NULL);
-
- // Write something into |net_log| (doesn't really have any meaning.)
- net_log.BeginEvent(NetLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE, NULL);
-
- results->UseNamedProxy(query_url.host());
-
- // Return a success code which represents the request's order.
- return request_count_++;
- }
-
- virtual void CancelRequest(RequestHandle request) {
- NOTREACHED();
- }
-
- virtual int SetPacScript(const GURL& pac_url,
- const string16& text,
- CompletionCallback* callback) {
- CheckIsOnWorkerThread();
- last_pac_script_ = text;
- return OK;
- }
-
- virtual void PurgeMemory() {
- CheckIsOnWorkerThread();
- ++purge_count_;
- }
-
- int purge_count() const { return purge_count_; }
-
- const string16& last_pac_script() const { return last_pac_script_; }
-
- void SetResolveLatency(int latency_ms) {
- resolve_latency_ms_ = latency_ms;
- }
-
- private:
- void CheckIsOnWorkerThread() {
- // We should be running on the worker thread -- while we don't know the
- // message loop of SingleThreadedProxyResolver's worker thread, we do
- // know that it is going to be distinct from the loop running the
- // test, so at least make sure it isn't the main loop.
- EXPECT_NE(MessageLoop::current(), wrong_loop_);
- }
-
- MessageLoop* wrong_loop_;
- int request_count_;
- int purge_count_;
- string16 last_pac_script_;
- int resolve_latency_ms_;
-};
-
-
-// A mock synchronous ProxyResolver which can be set to block upon reaching
-// GetProxyForURL().
-// TODO(eroman): WaitUntilBlocked() *must* be called before calling Unblock(),
-// otherwise there will be a race on |should_block_| since it is
-// read without any synchronization.
-class BlockableProxyResolver : public MockProxyResolver {
- public:
- BlockableProxyResolver()
- : should_block_(false),
- unblocked_(true, true),
- blocked_(true, false) {
- }
-
- void Block() {
- should_block_ = true;
- unblocked_.Reset();
- }
-
- void Unblock() {
- should_block_ = false;
- blocked_.Reset();
- unblocked_.Signal();
- }
-
- void WaitUntilBlocked() {
- blocked_.Wait();
- }
-
- virtual int GetProxyForURL(const GURL& query_url,
- ProxyInfo* results,
- CompletionCallback* callback,
- RequestHandle* request,
- const BoundNetLog& net_log) {
- if (should_block_) {
- blocked_.Signal();
- unblocked_.Wait();
- }
-
- return MockProxyResolver::GetProxyForURL(
- query_url, results, callback, request, net_log);
- }
-
- private:
- bool should_block_;
- base::WaitableEvent unblocked_;
- base::WaitableEvent blocked_;
-};
-
-TEST(SingleThreadedProxyResolverTest, Basic) {
- MockProxyResolver* mock = new MockProxyResolver;
- SingleThreadedProxyResolver resolver(mock);
-
- int rv;
-
- EXPECT_TRUE(resolver.expects_pac_bytes());
-
- // Call SetPacScriptByData() -- verify that it reaches the synchronous
- // resolver.
- TestCompletionCallback set_script_callback;
- rv = resolver.SetPacScriptByData(ASCIIToUTF16("pac script bytes"),
- &set_script_callback);
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, set_script_callback.WaitForResult());
- EXPECT_EQ(ASCIIToUTF16("pac script bytes"), mock->last_pac_script());
-
- // Start request 0.
- TestCompletionCallback callback0;
- CapturingBoundNetLog log0(CapturingNetLog::kUnbounded);
- ProxyInfo results0;
- rv = resolver.GetProxyForURL(
- GURL("http://request0"), &results0, &callback0, NULL, log0.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Wait for request 0 to finish.
- rv = callback0.WaitForResult();
- EXPECT_EQ(0, rv);
- EXPECT_EQ("PROXY request0:80", results0.ToPacString());
-
- // The mock proxy resolver should have written 1 log entry. And
- // on completion, this should have been copied into |log0|.
- EXPECT_EQ(1u, log0.entries().size());
-
- // Start 3 more requests (request1 to request3).
-
- TestCompletionCallback callback1;
- ProxyInfo results1;
- rv = resolver.GetProxyForURL(
- GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- TestCompletionCallback callback2;
- ProxyInfo results2;
- rv = resolver.GetProxyForURL(
- GURL("http://request2"), &results2, &callback2, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- TestCompletionCallback callback3;
- ProxyInfo results3;
- rv = resolver.GetProxyForURL(
- GURL("http://request3"), &results3, &callback3, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Wait for the requests to finish (they must finish in the order they were
- // started, which is what we check for from their magic return value)
-
- rv = callback1.WaitForResult();
- EXPECT_EQ(1, rv);
- EXPECT_EQ("PROXY request1:80", results1.ToPacString());
-
- rv = callback2.WaitForResult();
- EXPECT_EQ(2, rv);
- EXPECT_EQ("PROXY request2:80", results2.ToPacString());
-
- rv = callback3.WaitForResult();
- EXPECT_EQ(3, rv);
- EXPECT_EQ("PROXY request3:80", results3.ToPacString());
-
- // Ensure that PurgeMemory() reaches the wrapped resolver and happens on the
- // right thread.
- EXPECT_EQ(0, mock->purge_count());
- resolver.PurgeMemory();
- // There is no way to get a callback directly when PurgeMemory() completes, so
- // we queue up a dummy request after the PurgeMemory() call and wait until it
- // finishes to ensure PurgeMemory() has had a chance to run.
- TestCompletionCallback dummy_callback;
- rv = resolver.SetPacScriptByData(ASCIIToUTF16("dummy"), &dummy_callback);
- EXPECT_EQ(OK, dummy_callback.WaitForResult());
- EXPECT_EQ(1, mock->purge_count());
-}
-
-// Tests that the NetLog is updated to include the time the request was waiting
-// to be scheduled to a thread.
-TEST(SingleThreadedProxyResolverTest, UpdatesNetLogWithThreadWait) {
- BlockableProxyResolver* mock = new BlockableProxyResolver;
- SingleThreadedProxyResolver resolver(mock);
-
- int rv;
-
- // Block the proxy resolver, so no request can complete.
- mock->Block();
-
- // Start request 0.
- ProxyResolver::RequestHandle request0;
- TestCompletionCallback callback0;
- ProxyInfo results0;
- CapturingBoundNetLog log0(CapturingNetLog::kUnbounded);
- rv = resolver.GetProxyForURL(
- GURL("http://request0"), &results0, &callback0, &request0, log0.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Start 2 more requests (request1 and request2).
-
- TestCompletionCallback callback1;
- ProxyInfo results1;
- CapturingBoundNetLog log1(CapturingNetLog::kUnbounded);
- rv = resolver.GetProxyForURL(
- GURL("http://request1"), &results1, &callback1, NULL, log1.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ProxyResolver::RequestHandle request2;
- TestCompletionCallback callback2;
- ProxyInfo results2;
- CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
- rv = resolver.GetProxyForURL(
- GURL("http://request2"), &results2, &callback2, &request2, log2.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Unblock the worker thread so the requests can continue running.
- mock->WaitUntilBlocked();
- mock->Unblock();
-
- // Check that request 0 completed as expected.
- // The NetLog only has 1 entry (that came from the mock proxy resolver.)
- EXPECT_EQ(0, callback0.WaitForResult());
- EXPECT_EQ("PROXY request0:80", results0.ToPacString());
- ASSERT_EQ(1u, log0.entries().size());
-
- // Check that request 1 completed as expected.
- EXPECT_EQ(1, callback1.WaitForResult());
- EXPECT_EQ("PROXY request1:80", results1.ToPacString());
- ASSERT_EQ(3u, log1.entries().size());
- EXPECT_TRUE(LogContainsBeginEvent(
- log1.entries(), 0,
- NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD));
- EXPECT_TRUE(LogContainsEndEvent(
- log1.entries(), 1,
- NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD));
-
- // Check that request 2 completed as expected.
- EXPECT_EQ(2, callback2.WaitForResult());
- EXPECT_EQ("PROXY request2:80", results2.ToPacString());
- ASSERT_EQ(3u, log2.entries().size());
- EXPECT_TRUE(LogContainsBeginEvent(
- log2.entries(), 0,
- NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD));
- EXPECT_TRUE(LogContainsEndEvent(
- log2.entries(), 1,
- NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD));
-}
-
-// Cancel a request which is in progress, and then cancel a request which
-// is pending.
-TEST(SingleThreadedProxyResolverTest, CancelRequest) {
- BlockableProxyResolver* mock = new BlockableProxyResolver;
- SingleThreadedProxyResolver resolver(mock);
-
- int rv;
-
- // Block the proxy resolver, so no request can complete.
- mock->Block();
-
- // Start request 0.
- ProxyResolver::RequestHandle request0;
- TestCompletionCallback callback0;
- ProxyInfo results0;
- rv = resolver.GetProxyForURL(
- GURL("http://request0"), &results0, &callback0, &request0, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Wait until requests 0 reaches the worker thread.
- mock->WaitUntilBlocked();
-
- // Start 3 more requests (request1 : request3).
-
- TestCompletionCallback callback1;
- ProxyInfo results1;
- rv = resolver.GetProxyForURL(
- GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ProxyResolver::RequestHandle request2;
- TestCompletionCallback callback2;
- ProxyInfo results2;
- rv = resolver.GetProxyForURL(
- GURL("http://request2"), &results2, &callback2, &request2, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- TestCompletionCallback callback3;
- ProxyInfo results3;
- rv = resolver.GetProxyForURL(
- GURL("http://request3"), &results3, &callback3, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Cancel request0 (inprogress) and request2 (pending).
- resolver.CancelRequest(request0);
- resolver.CancelRequest(request2);
-
- // Unblock the worker thread so the requests can continue running.
- mock->Unblock();
-
- // Wait for requests 1 and 3 to finish.
-
- rv = callback1.WaitForResult();
- EXPECT_EQ(1, rv);
- EXPECT_EQ("PROXY request1:80", results1.ToPacString());
-
- rv = callback3.WaitForResult();
- // Note that since request2 was cancelled before reaching the resolver,
- // the request count is 2 and not 3 here.
- EXPECT_EQ(2, rv);
- EXPECT_EQ("PROXY request3:80", results3.ToPacString());
-
- // Requests 0 and 2 which were cancelled, hence their completion callbacks
- // were never summoned.
- EXPECT_FALSE(callback0.have_result());
- EXPECT_FALSE(callback2.have_result());
-}
-
-// Test that deleting SingleThreadedProxyResolver while requests are
-// outstanding cancels them (and doesn't leak anything).
-TEST(SingleThreadedProxyResolverTest, CancelRequestByDeleting) {
- BlockableProxyResolver* mock = new BlockableProxyResolver;
- scoped_ptr<SingleThreadedProxyResolver> resolver(
- new SingleThreadedProxyResolver(mock));
-
- int rv;
-
- // Block the proxy resolver, so no request can complete.
- mock->Block();
-
- // Start 3 requests.
-
- TestCompletionCallback callback0;
- ProxyInfo results0;
- rv = resolver->GetProxyForURL(
- GURL("http://request0"), &results0, &callback0, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- TestCompletionCallback callback1;
- ProxyInfo results1;
- rv = resolver->GetProxyForURL(
- GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- TestCompletionCallback callback2;
- ProxyInfo results2;
- rv = resolver->GetProxyForURL(
- GURL("http://request2"), &results2, &callback2, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Wait until request 0 reaches the worker thread.
- mock->WaitUntilBlocked();
-
- // Add some latency, to improve the chance that when
- // SingleThreadedProxyResolver is deleted below we are still running inside
- // of the worker thread. The test will pass regardless, so this race doesn't
- // cause flakiness. However the destruction during execution is a more
- // interesting case to test.
- mock->SetResolveLatency(100);
-
- // Unblock the worker thread and delete the underlying
- // SingleThreadedProxyResolver immediately.
- mock->Unblock();
- resolver.reset();
-
- // Give any posted tasks a chance to run (in case there is badness).
- MessageLoop::current()->RunAllPending();
-
- // Check that none of the outstanding requests were completed.
- EXPECT_FALSE(callback0.have_result());
- EXPECT_FALSE(callback1.have_result());
- EXPECT_FALSE(callback2.have_result());
-}
-
-// Cancel an outstanding call to SetPacScriptByData().
-TEST(SingleThreadedProxyResolverTest, CancelSetPacScript) {
- BlockableProxyResolver* mock = new BlockableProxyResolver;
- SingleThreadedProxyResolver resolver(mock);
-
- int rv;
-
- // Block the proxy resolver, so no request can complete.
- mock->Block();
-
- // Start request 0.
- ProxyResolver::RequestHandle request0;
- TestCompletionCallback callback0;
- ProxyInfo results0;
- rv = resolver.GetProxyForURL(
- GURL("http://request0"), &results0, &callback0, &request0, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Wait until requests 0 reaches the worker thread.
- mock->WaitUntilBlocked();
-
- TestCompletionCallback set_pac_script_callback;
- rv = resolver.SetPacScriptByData(ASCIIToUTF16("data"),
- &set_pac_script_callback);
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Cancel the SetPacScriptByData request (it can't have finished yet,
- // since the single-thread is currently blocked).
- resolver.CancelSetPacScript();
-
- // Start 1 more request.
-
- TestCompletionCallback callback1;
- ProxyInfo results1;
- rv = resolver.GetProxyForURL(
- GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Unblock the worker thread so the requests can continue running.
- mock->Unblock();
-
- // Wait for requests 0 and 1 to finish.
-
- rv = callback0.WaitForResult();
- EXPECT_EQ(0, rv);
- EXPECT_EQ("PROXY request0:80", results0.ToPacString());
-
- rv = callback1.WaitForResult();
- EXPECT_EQ(1, rv);
- EXPECT_EQ("PROXY request1:80", results1.ToPacString());
-
- // The SetPacScript callback should never have been completed.
- EXPECT_FALSE(set_pac_script_callback.have_result());
-}
-
-} // namespace
-} // namespace net
« no previous file with comments | « net/proxy/single_threaded_proxy_resolver.cc ('k') | net/proxy/sync_host_resolver_bridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698