| Index: chrome/browser/sync/glue/http_bridge_unittest.cc
|
| diff --git a/chrome/browser/sync/glue/http_bridge_unittest.cc b/chrome/browser/sync/glue/http_bridge_unittest.cc
|
| deleted file mode 100644
|
| index 745350d0109e2854da0de4d7b45a2a0613ee48c7..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/sync/glue/http_bridge_unittest.cc
|
| +++ /dev/null
|
| @@ -1,411 +0,0 @@
|
| -// Copyright (c) 2012 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/message_loop_proxy.h"
|
| -#include "base/synchronization/waitable_event.h"
|
| -#include "base/threading/thread.h"
|
| -#include "chrome/browser/sync/glue/http_bridge.h"
|
| -#include "content/public/test/test_browser_thread.h"
|
| -#include "net/test/test_server.h"
|
| -#include "net/url_request/test_url_fetcher_factory.h"
|
| -#include "net/url_request/url_fetcher_delegate.h"
|
| -#include "net/url_request/url_request_test_util.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using browser_sync::HttpBridge;
|
| -using content::BrowserThread;
|
| -
|
| -namespace {
|
| -// TODO(timsteele): Should use PathService here. See Chromium Issue 3113.
|
| -const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");
|
| -}
|
| -
|
| -class SyncHttpBridgeTest : public testing::Test {
|
| - public:
|
| - SyncHttpBridgeTest()
|
| - : test_server_(net::TestServer::TYPE_HTTP,
|
| - net::TestServer::kLocalhost,
|
| - FilePath(kDocRoot)),
|
| - fake_default_request_context_getter_(NULL),
|
| - bridge_for_race_test_(NULL),
|
| - io_thread_(BrowserThread::IO) {
|
| - }
|
| -
|
| - virtual void SetUp() {
|
| - io_thread_.StartIOThread();
|
| - }
|
| -
|
| - virtual void TearDown() {
|
| - if (fake_default_request_context_getter_) {
|
| - GetIOThreadLoop()->ReleaseSoon(FROM_HERE,
|
| - fake_default_request_context_getter_);
|
| - fake_default_request_context_getter_ = NULL;
|
| - }
|
| - io_thread_.Stop();
|
| - }
|
| -
|
| - HttpBridge* BuildBridge() {
|
| - if (!fake_default_request_context_getter_) {
|
| - fake_default_request_context_getter_ =
|
| - new TestURLRequestContextGetter(
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
|
| - fake_default_request_context_getter_->AddRef();
|
| - }
|
| - HttpBridge* bridge = new HttpBridge(
|
| - new HttpBridge::RequestContextGetter(
|
| - fake_default_request_context_getter_));
|
| - return bridge;
|
| - }
|
| -
|
| - static void Abort(HttpBridge* bridge) {
|
| - bridge->Abort();
|
| - }
|
| -
|
| - // Used by AbortAndReleaseBeforeFetchCompletes to test an interesting race
|
| - // condition.
|
| - void RunSyncThreadBridgeUseTest(base::WaitableEvent* signal_when_created,
|
| - base::WaitableEvent* signal_when_released);
|
| -
|
| - static void TestSameHttpNetworkSession(MessageLoop* main_message_loop,
|
| - SyncHttpBridgeTest* test) {
|
| - scoped_refptr<HttpBridge> http_bridge(test->BuildBridge());
|
| - EXPECT_TRUE(test->GetTestRequestContextGetter());
|
| - net::HttpNetworkSession* test_session =
|
| - test->GetTestRequestContextGetter()->GetURLRequestContext()->
|
| - http_transaction_factory()->GetSession();
|
| - EXPECT_EQ(test_session,
|
| - http_bridge->GetRequestContextGetter()->
|
| - GetURLRequestContext()->
|
| - http_transaction_factory()->GetSession());
|
| - main_message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
|
| - }
|
| -
|
| - MessageLoop* GetIOThreadLoop() {
|
| - return io_thread_.DeprecatedGetThreadObject()->message_loop();
|
| - }
|
| -
|
| - // Note this is lazy created, so don't call this before your bridge.
|
| - TestURLRequestContextGetter* GetTestRequestContextGetter() {
|
| - return fake_default_request_context_getter_;
|
| - }
|
| -
|
| - net::TestServer test_server_;
|
| -
|
| - content::TestBrowserThread* io_thread() { return &io_thread_; }
|
| -
|
| - HttpBridge* bridge_for_race_test() { return bridge_for_race_test_; }
|
| -
|
| - private:
|
| - // A make-believe "default" request context, as would be returned by
|
| - // Profile::GetDefaultRequestContext(). Created lazily by BuildBridge.
|
| - TestURLRequestContextGetter* fake_default_request_context_getter_;
|
| -
|
| - HttpBridge* bridge_for_race_test_;
|
| -
|
| - // Separate thread for IO used by the HttpBridge.
|
| - content::TestBrowserThread io_thread_;
|
| - MessageLoop loop_;
|
| -};
|
| -
|
| -// An HttpBridge that doesn't actually make network requests and just calls
|
| -// back with dummy response info.
|
| -// TODO(tim): Instead of inheriting here we should inject a component
|
| -// responsible for the MakeAsynchronousPost bit.
|
| -class ShuntedHttpBridge : public HttpBridge {
|
| - public:
|
| - // If |never_finishes| is true, the simulated request never actually
|
| - // returns.
|
| - ShuntedHttpBridge(net::URLRequestContextGetter* baseline_context_getter,
|
| - SyncHttpBridgeTest* test, bool never_finishes)
|
| - : HttpBridge(new HttpBridge::RequestContextGetter(
|
| - baseline_context_getter)),
|
| - test_(test), never_finishes_(never_finishes) { }
|
| - protected:
|
| - virtual void MakeAsynchronousPost() {
|
| - ASSERT_TRUE(MessageLoop::current() == test_->GetIOThreadLoop());
|
| - if (never_finishes_)
|
| - return;
|
| -
|
| - // We don't actually want to make a request for this test, so just callback
|
| - // as if it completed.
|
| - test_->GetIOThreadLoop()->PostTask(FROM_HERE,
|
| - base::Bind(&ShuntedHttpBridge::CallOnURLFetchComplete, this));
|
| - }
|
| - private:
|
| - ~ShuntedHttpBridge() {}
|
| -
|
| - void CallOnURLFetchComplete() {
|
| - ASSERT_TRUE(MessageLoop::current() == test_->GetIOThreadLoop());
|
| - // We return no cookies and a dummy content response.
|
| - net::ResponseCookies cookies;
|
| -
|
| - std::string response_content = "success!";
|
| - net::TestURLFetcher fetcher(0, GURL(), NULL);
|
| - fetcher.set_url(GURL("www.google.com"));
|
| - fetcher.set_response_code(200);
|
| - fetcher.set_cookies(cookies);
|
| - fetcher.SetResponseString(response_content);
|
| - OnURLFetchComplete(&fetcher);
|
| - }
|
| - SyncHttpBridgeTest* test_;
|
| - bool never_finishes_;
|
| -};
|
| -
|
| -void SyncHttpBridgeTest::RunSyncThreadBridgeUseTest(
|
| - base::WaitableEvent* signal_when_created,
|
| - base::WaitableEvent* signal_when_released) {
|
| - scoped_refptr<net::URLRequestContextGetter> ctx_getter(
|
| - new TestURLRequestContextGetter(
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
|
| - {
|
| - scoped_refptr<ShuntedHttpBridge> bridge(new ShuntedHttpBridge(
|
| - ctx_getter, this, true));
|
| - bridge->SetUserAgent("bob");
|
| - bridge->SetURL("http://www.google.com", 9999);
|
| - bridge->SetPostPayload("text/plain", 2, " ");
|
| - bridge_for_race_test_ = bridge;
|
| - signal_when_created->Signal();
|
| -
|
| - int os_error = 0;
|
| - int response_code = 0;
|
| - bridge->MakeSynchronousPost(&os_error, &response_code);
|
| - bridge_for_race_test_ = NULL;
|
| - }
|
| - signal_when_released->Signal();
|
| -}
|
| -
|
| -TEST_F(SyncHttpBridgeTest, TestUsesSameHttpNetworkSession) {
|
| - // Run this test on the IO thread because we can only call
|
| - // URLRequestContextGetter::GetURLRequestContext on the IO thread.
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&SyncHttpBridgeTest::TestSameHttpNetworkSession,
|
| - MessageLoop::current(), this));
|
| - MessageLoop::current()->Run();
|
| -}
|
| -
|
| -// Test the HttpBridge without actually making any network requests.
|
| -TEST_F(SyncHttpBridgeTest, TestMakeSynchronousPostShunted) {
|
| - scoped_refptr<net::URLRequestContextGetter> ctx_getter(
|
| - new TestURLRequestContextGetter(
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
|
| - scoped_refptr<HttpBridge> http_bridge(new ShuntedHttpBridge(
|
| - ctx_getter, this, false));
|
| - http_bridge->SetUserAgent("bob");
|
| - http_bridge->SetURL("http://www.google.com", 9999);
|
| - http_bridge->SetPostPayload("text/plain", 2, " ");
|
| -
|
| - int os_error = 0;
|
| - int response_code = 0;
|
| - bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
|
| - EXPECT_TRUE(success);
|
| - EXPECT_EQ(200, response_code);
|
| - EXPECT_EQ(0, os_error);
|
| -
|
| - EXPECT_EQ(8, http_bridge->GetResponseContentLength());
|
| - EXPECT_EQ(std::string("success!"),
|
| - std::string(http_bridge->GetResponseContent()));
|
| -}
|
| -
|
| -// Full round-trip test of the HttpBridge, using default UA string and
|
| -// no request cookies.
|
| -TEST_F(SyncHttpBridgeTest, TestMakeSynchronousPostLiveWithPayload) {
|
| - ASSERT_TRUE(test_server_.Start());
|
| -
|
| - scoped_refptr<HttpBridge> http_bridge(BuildBridge());
|
| -
|
| - std::string payload = "this should be echoed back";
|
| - GURL echo = test_server_.GetURL("echo");
|
| - http_bridge->SetURL(echo.spec().c_str(), echo.IntPort());
|
| - http_bridge->SetPostPayload("application/x-www-form-urlencoded",
|
| - payload.length() + 1, payload.c_str());
|
| - int os_error = 0;
|
| - int response_code = 0;
|
| - bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
|
| - EXPECT_TRUE(success);
|
| - EXPECT_EQ(200, response_code);
|
| - EXPECT_EQ(0, os_error);
|
| -
|
| - EXPECT_EQ(payload.length() + 1,
|
| - static_cast<size_t>(http_bridge->GetResponseContentLength()));
|
| - EXPECT_EQ(payload, std::string(http_bridge->GetResponseContent()));
|
| -}
|
| -
|
| -// Full round-trip test of the HttpBridge, using custom UA string
|
| -TEST_F(SyncHttpBridgeTest, TestMakeSynchronousPostLiveComprehensive) {
|
| - ASSERT_TRUE(test_server_.Start());
|
| -
|
| - scoped_refptr<HttpBridge> http_bridge(BuildBridge());
|
| -
|
| - GURL echo_header = test_server_.GetURL("echoall");
|
| - http_bridge->SetUserAgent("bob");
|
| - http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
|
| -
|
| - std::string test_payload = "###TEST PAYLOAD###";
|
| - http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
|
| - test_payload.c_str());
|
| -
|
| - int os_error = 0;
|
| - int response_code = 0;
|
| - bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
|
| - EXPECT_TRUE(success);
|
| - EXPECT_EQ(200, response_code);
|
| - EXPECT_EQ(0, os_error);
|
| -
|
| - std::string response(http_bridge->GetResponseContent(),
|
| - http_bridge->GetResponseContentLength());
|
| - EXPECT_EQ(std::string::npos, response.find("Cookie:"));
|
| - EXPECT_NE(std::string::npos, response.find("User-Agent: bob"));
|
| - EXPECT_NE(std::string::npos, response.find(test_payload.c_str()));
|
| -}
|
| -
|
| -TEST_F(SyncHttpBridgeTest, TestExtraRequestHeaders) {
|
| - ASSERT_TRUE(test_server_.Start());
|
| -
|
| - scoped_refptr<HttpBridge> http_bridge(BuildBridge());
|
| -
|
| - GURL echo_header = test_server_.GetURL("echoall");
|
| -
|
| - http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
|
| - http_bridge->SetExtraRequestHeaders("test:fnord");
|
| -
|
| - std::string test_payload = "###TEST PAYLOAD###";
|
| - http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
|
| - test_payload.c_str());
|
| -
|
| - int os_error = 0;
|
| - int response_code = 0;
|
| - bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
|
| - EXPECT_TRUE(success);
|
| - EXPECT_EQ(200, response_code);
|
| - EXPECT_EQ(0, os_error);
|
| -
|
| - std::string response(http_bridge->GetResponseContent(),
|
| - http_bridge->GetResponseContentLength());
|
| -
|
| - EXPECT_NE(std::string::npos, response.find("fnord"));
|
| - EXPECT_NE(std::string::npos, response.find(test_payload.c_str()));
|
| -}
|
| -
|
| -TEST_F(SyncHttpBridgeTest, TestResponseHeader) {
|
| - ASSERT_TRUE(test_server_.Start());
|
| -
|
| - scoped_refptr<HttpBridge> http_bridge(BuildBridge());
|
| -
|
| - GURL echo_header = test_server_.GetURL("echoall");
|
| - http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
|
| -
|
| - std::string test_payload = "###TEST PAYLOAD###";
|
| - http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
|
| - test_payload.c_str());
|
| -
|
| - int os_error = 0;
|
| - int response_code = 0;
|
| - bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
|
| - EXPECT_TRUE(success);
|
| - EXPECT_EQ(200, response_code);
|
| - EXPECT_EQ(0, os_error);
|
| -
|
| - EXPECT_EQ(http_bridge->GetResponseHeaderValue("Content-type"), "text/html");
|
| - EXPECT_TRUE(http_bridge->GetResponseHeaderValue("invalid-header").empty());
|
| -}
|
| -
|
| -TEST_F(SyncHttpBridgeTest, Abort) {
|
| - scoped_refptr<net::URLRequestContextGetter> ctx_getter(
|
| - new TestURLRequestContextGetter(
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
|
| - scoped_refptr<ShuntedHttpBridge> http_bridge(new ShuntedHttpBridge(
|
| - ctx_getter, this, true));
|
| - http_bridge->SetUserAgent("bob");
|
| - http_bridge->SetURL("http://www.google.com", 9999);
|
| - http_bridge->SetPostPayload("text/plain", 2, " ");
|
| -
|
| - int os_error = 0;
|
| - int response_code = 0;
|
| -
|
| - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&SyncHttpBridgeTest::Abort, http_bridge));
|
| - bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
|
| - EXPECT_FALSE(success);
|
| - EXPECT_EQ(net::ERR_ABORTED, os_error);
|
| -}
|
| -
|
| -TEST_F(SyncHttpBridgeTest, AbortLate) {
|
| - scoped_refptr<net::URLRequestContextGetter> ctx_getter(
|
| - new TestURLRequestContextGetter(
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
|
| - scoped_refptr<ShuntedHttpBridge> http_bridge(new ShuntedHttpBridge(
|
| - ctx_getter, this, false));
|
| - http_bridge->SetUserAgent("bob");
|
| - http_bridge->SetURL("http://www.google.com", 9999);
|
| - http_bridge->SetPostPayload("text/plain", 2, " ");
|
| -
|
| - int os_error = 0;
|
| - int response_code = 0;
|
| -
|
| - bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
|
| - ASSERT_TRUE(success);
|
| - http_bridge->Abort();
|
| - // Ensures no double-free of URLFetcher, etc.
|
| -}
|
| -
|
| -// Tests an interesting case where code using the HttpBridge aborts the fetch
|
| -// and releases ownership before a pending fetch completed callback is issued by
|
| -// the underlying URLFetcher (and before that URLFetcher is destroyed, which
|
| -// would cancel the callback).
|
| -TEST_F(SyncHttpBridgeTest, AbortAndReleaseBeforeFetchComplete) {
|
| - base::Thread sync_thread("SyncThread");
|
| - sync_thread.Start();
|
| -
|
| - // First, block the sync thread on the post.
|
| - base::WaitableEvent signal_when_created(false, false);
|
| - base::WaitableEvent signal_when_released(false, false);
|
| - sync_thread.message_loop()->PostTask(FROM_HERE,
|
| - base::Bind(&SyncHttpBridgeTest::RunSyncThreadBridgeUseTest,
|
| - base::Unretained(this),
|
| - &signal_when_created,
|
| - &signal_when_released));
|
| -
|
| - // Stop IO so we can control order of operations.
|
| - base::WaitableEvent io_waiter(false, false);
|
| - ASSERT_TRUE(BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&base::WaitableEvent::Wait, base::Unretained(&io_waiter))));
|
| -
|
| - signal_when_created.Wait(); // Wait till we have a bridge to abort.
|
| - ASSERT_TRUE(bridge_for_race_test());
|
| -
|
| - // Schedule the fetch completion callback (but don't run it yet). Don't take
|
| - // a reference to the bridge to mimic URLFetcher's handling of the delegate.
|
| - net::URLFetcherDelegate* delegate =
|
| - static_cast<net::URLFetcherDelegate*>(bridge_for_race_test());
|
| - net::ResponseCookies cookies;
|
| - std::string response_content = "success!";
|
| - net::TestURLFetcher fetcher(0, GURL(), NULL);
|
| - fetcher.set_url(GURL("www.google.com"));
|
| - fetcher.set_response_code(200);
|
| - fetcher.set_cookies(cookies);
|
| - fetcher.SetResponseString(response_content);
|
| - ASSERT_TRUE(BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&net::URLFetcherDelegate::OnURLFetchComplete,
|
| - base::Unretained(delegate), &fetcher)));
|
| -
|
| - // Abort the fetch. This should be smart enough to handle the case where
|
| - // the bridge is destroyed before the callback scheduled above completes.
|
| - bridge_for_race_test()->Abort();
|
| -
|
| - // Wait until the sync thread releases its ref on the bridge.
|
| - signal_when_released.Wait();
|
| - ASSERT_FALSE(bridge_for_race_test());
|
| -
|
| - // Unleash the hounds. The fetch completion callback should fire first, and
|
| - // succeed even though we Release()d the bridge above because the call to
|
| - // Abort should have held a reference.
|
| - io_waiter.Signal();
|
| -
|
| - // Done.
|
| - sync_thread.Stop();
|
| - io_thread()->Stop();
|
| -}
|
|
|