summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 04:02:56 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 04:02:56 +0000
commit244932d545ce1bea5e1724d3a77c5064fa567eb2 (patch)
treeaaed157a5e258ce1accda2c2b9618c64d8180010
parent9da582be89b7c9ab891383c6d6c26e370c7f579c (diff)
downloadchromium_src-244932d545ce1bea5e1724d3a77c5064fa567eb2.zip
chromium_src-244932d545ce1bea5e1724d3a77c5064fa567eb2.tar.gz
chromium_src-244932d545ce1bea5e1724d3a77c5064fa567eb2.tar.bz2
Do not spawn a thread in browser/interactive ui tests before spawning sandbox host process
* Introduced DBThreadManager::SetInstanceForTesting to specify the instance to be used when DBThreadManager::Initialize is called in the browser setup rocess. * Temporarily stop the thread in EmbeddedTestServer to fork/exec sandbox host process properly. BUG=322732 TBR=sky@chromium.org Review URL: https://codereview.chromium.org/83633004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238554 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/apps/app_browsertest.cc3
-rw-r--r--chrome/browser/chromeos/login/crash_restore_browsertest.cc2
-rw-r--r--chrome/browser/chromeos/login/kiosk_browsertest.cc11
-rw-r--r--chrome/browser/chromeos/login/screen_locker_browsertest.cc2
-rw-r--r--chrome/browser/chromeos/login/screens/network_screen_browsertest.cc3
-rw-r--r--chrome/browser/chromeos/login/screens/update_screen_browsertest.cc3
-rw-r--r--chrome/browser/chromeos/login/wizard_controller_browsertest.cc3
-rw-r--r--chrome/browser/chromeos/policy/device_local_account_browsertest.cc6
-rw-r--r--chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc3
-rw-r--r--chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc3
-rw-r--r--chrome/browser/extensions/api/system_private/system_private_apitest.cc4
-rw-r--r--chromeos/dbus/dbus_thread_manager.cc37
-rw-r--r--chromeos/dbus/dbus_thread_manager.h16
-rw-r--r--content/browser/renderer_host/render_sandbox_host_linux.cc3
-rw-r--r--content/public/test/browser_test_base.cc2
-rw-r--r--net/test/embedded_test_server/embedded_test_server.cc39
-rw-r--r--net/test/embedded_test_server/embedded_test_server.h43
17 files changed, 119 insertions, 64 deletions
diff --git a/chrome/browser/apps/app_browsertest.cc b/chrome/browser/apps/app_browsertest.cc
index 39356b5..f2c1ab5 100644
--- a/chrome/browser/apps/app_browsertest.cc
+++ b/chrome/browser/apps/app_browsertest.cc
@@ -1235,7 +1235,7 @@ class RestartDeviceTest : public PlatformAppBrowserTest {
power_manager_client_ = new chromeos::FakePowerManagerClient;
dbus_manager->SetPowerManagerClient(
scoped_ptr<chromeos::PowerManagerClient>(power_manager_client_));
- chromeos::DBusThreadManager::InitializeForTesting(dbus_manager);
+ chromeos::DBusThreadManager::SetInstanceForTesting(dbus_manager);
}
virtual void SetUpOnMainThread() OVERRIDE {
@@ -1257,7 +1257,6 @@ class RestartDeviceTest : public PlatformAppBrowserTest {
}
virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
- chromeos::DBusThreadManager::Shutdown();
PlatformAppBrowserTest::TearDownInProcessBrowserTestFixture();
}
diff --git a/chrome/browser/chromeos/login/crash_restore_browsertest.cc b/chrome/browser/chromeos/login/crash_restore_browsertest.cc
index ebd8f25..8bcaaf5 100644
--- a/chrome/browser/chromeos/login/crash_restore_browsertest.cc
+++ b/chrome/browser/chromeos/login/crash_restore_browsertest.cc
@@ -52,7 +52,7 @@ class CrashRestoreSimpleTest : public InProcessBrowserTest {
session_manager_client_ = new FakeSessionManagerClient;
dbus_thread_manager->SetSessionManagerClient(
scoped_ptr<SessionManagerClient>(session_manager_client_));
- DBusThreadManager::InitializeForTesting(dbus_thread_manager);
+ DBusThreadManager::SetInstanceForTesting(dbus_thread_manager);
session_manager_client_->StartSession(kUserId1);
}
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc
index fd11881..fd65deb 100644
--- a/chrome/browser/chromeos/login/kiosk_browsertest.cc
+++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -249,6 +249,9 @@ class KioskTest : public InProcessBrowserTest {
embedded_test_server()->RegisterRequestHandler(
base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ // Stop IO thread here because no threads are allowed while
+ // spawning sandbox host process. See crbug.com/322732.
+ embedded_test_server()->StopThread();
mock_user_manager_.reset(new MockUserManager);
AppLaunchController::SkipSplashWaitForTesting();
@@ -261,6 +264,11 @@ class KioskTest : public InProcessBrowserTest {
host_resolver()->AddRule("*", "127.0.0.1");
}
+ virtual void SetUpOnMainThread() OVERRIDE {
+ // Restart the thread as the sandbox host process has already been spawned.
+ embedded_test_server()->RestartThreadAndListen();
+ }
+
virtual void CleanUpOnMainThread() OVERRIDE {
// We need to clean up these objects in this specific order.
fake_network_notifier_.reset(NULL);
@@ -801,6 +809,7 @@ class KioskEnterpriseTest : public KioskTest {
}
virtual void SetUpOnMainThread() OVERRIDE {
+ KioskTest::SetUpOnMainThread();
// Configure kTestEnterpriseKioskApp in device policy.
em::DeviceLocalAccountsProto* accounts =
device_policy_test_helper_.device_policy()->payload()
@@ -832,8 +841,6 @@ class KioskEnterpriseTest : public KioskTest {
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(token_service);
token_service->SetAndSaveRefreshToken(kTestRefreshToken);
-
- KioskTest::SetUpOnMainThread();
}
static void StorePolicyCallback(bool result) {
diff --git a/chrome/browser/chromeos/login/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/screen_locker_browsertest.cc
index a441577..c9f721b 100644
--- a/chrome/browser/chromeos/login/screen_locker_browsertest.cc
+++ b/chrome/browser/chromeos/login/screen_locker_browsertest.cc
@@ -121,7 +121,7 @@ class ScreenLockerTest : public InProcessBrowserTest {
fake_session_manager_client_ = new FakeSessionManagerClient;
fake_dbus_thread_manager->SetSessionManagerClient(
scoped_ptr<SessionManagerClient>(fake_session_manager_client_));
- DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
+ DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager);
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
diff --git a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc
index e06fc9f..a77d14c 100644
--- a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc
@@ -58,7 +58,7 @@ class NetworkScreenTest : public WizardInProcessBrowserTest {
fake_session_manager_client_ = new FakeSessionManagerClient;
fake_dbus_thread_manager->SetSessionManagerClient(
scoped_ptr<SessionManagerClient>(fake_session_manager_client_));
- DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
+ DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager);
}
virtual void SetUpOnMainThread() OVERRIDE {
@@ -80,7 +80,6 @@ class NetworkScreenTest : public WizardInProcessBrowserTest {
virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
- DBusThreadManager::Shutdown();
}
void EmulateContinueButtonExit(NetworkScreen* network_screen) {
diff --git a/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc
index a56d55e..b3aefe7 100644
--- a/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc
@@ -49,7 +49,7 @@ class UpdateScreenTest : public WizardInProcessBrowserTest {
fake_dbus_thread_manager->SetUpdateEngineClient(
scoped_ptr<UpdateEngineClient>(fake_update_engine_client_));
- DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
+ DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager);
WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
// Setup network portal detector to return online state for both
@@ -90,7 +90,6 @@ class UpdateScreenTest : public WizardInProcessBrowserTest {
virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
NetworkPortalDetector::Shutdown();
WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
- DBusThreadManager::Shutdown();
}
void SetDefaultNetworkPath(const std::string& service_path) {
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
index c20afe2..6df0520 100644
--- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -454,7 +454,7 @@ class WizardControllerBrokenLocalStateTest : public WizardControllerTest {
fake_session_manager_client_ = new FakeSessionManagerClient;
fake_dbus_thread_manager->SetSessionManagerClient(
scoped_ptr<SessionManagerClient>(fake_session_manager_client_));
- DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
+ DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager);
}
virtual void SetUpOnMainThread() OVERRIDE {
@@ -471,7 +471,6 @@ class WizardControllerBrokenLocalStateTest : public WizardControllerTest {
virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
WizardControllerTest::TearDownInProcessBrowserTestFixture();
- DBusThreadManager::Shutdown();
}
ErrorScreen* GetErrorScreen() {
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index a95e225..2015aab 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -74,10 +74,7 @@
#include "chrome/common/chrome_switches.h"
#include "chromeos/chromeos_paths.h"
#include "chromeos/chromeos_switches.h"
-#include "chromeos/dbus/cryptohome_client.h"
-#include "chromeos/dbus/dbus_method_call_status.h"
#include "chromeos/dbus/fake_session_manager_client.h"
-#include "chromeos/dbus/session_manager_client.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_namespace.h"
@@ -101,7 +98,7 @@
#include "net/url_request/url_request_status.h"
#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
+//#include "third_party/cros_system_api/dbus/service_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
@@ -296,7 +293,6 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest {
external_data_cache_dir_override_.reset(new base::ScopedPathOverride(
chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTERNAL_DATA,
external_data_cache_dir_.path()));
-
DevicePolicyCrosBrowserTest::SetUp();
}
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
index eb8505c..aa617ab 100644
--- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
+++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
@@ -83,13 +83,12 @@ DevicePolicyCrosBrowserTest::~DevicePolicyCrosBrowserTest() {
}
void DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture() {
- chromeos::DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager_);
+ chromeos::DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager_);
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
}
void DevicePolicyCrosBrowserTest::TearDownInProcessBrowserTestFixture() {
InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
- chromeos::DBusThreadManager::Shutdown();
}
void DevicePolicyCrosBrowserTest::MarkAsEnterpriseOwned() {
diff --git a/chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc b/chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc
index c14d41d..1e6e8e9 100644
--- a/chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc
+++ b/chrome/browser/chromeos/power/peripheral_battery_observer_browsertest.cc
@@ -40,7 +40,7 @@ class PeripheralBatteryObserverTest : public InProcessBrowserTest {
FakeDBusThreadManager* fake_dbus_thread_manager =
new FakeDBusThreadManager;
fake_dbus_thread_manager->SetFakeClients();
- DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
+ DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager);
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
}
@@ -54,7 +54,6 @@ class PeripheralBatteryObserverTest : public InProcessBrowserTest {
virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
- DBusThreadManager::Shutdown();
}
protected:
diff --git a/chrome/browser/extensions/api/system_private/system_private_apitest.cc b/chrome/browser/extensions/api/system_private/system_private_apitest.cc
index b49b396..f242095 100644
--- a/chrome/browser/extensions/api/system_private/system_private_apitest.cc
+++ b/chrome/browser/extensions/api/system_private/system_private_apitest.cc
@@ -37,11 +37,11 @@ class GetUpdateStatusApiTest : public ExtensionApiTest {
fake_update_engine_client_ = new chromeos::FakeUpdateEngineClient;
fake_dbus_thread_manager->SetUpdateEngineClient(
scoped_ptr<UpdateEngineClient>(fake_update_engine_client_));
- chromeos::DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
+ chromeos::DBusThreadManager::SetInstanceForTesting(
+ fake_dbus_thread_manager);
}
virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
- chromeos::DBusThreadManager::Shutdown();
ExtensionApiTest::TearDownInProcessBrowserTestFixture();
}
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc
index 7a8a417..ab02152 100644
--- a/chromeos/dbus/dbus_thread_manager.cc
+++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -51,7 +51,7 @@
namespace chromeos {
static DBusThreadManager* g_dbus_thread_manager = NULL;
-static bool g_dbus_thread_manager_set_for_testing = false;
+static DBusThreadManager* g_dbus_thread_manager_for_testing = NULL;
// The DBusThreadManager implementation used in production.
class DBusThreadManagerImpl : public DBusThreadManager {
@@ -319,13 +319,16 @@ class DBusThreadManagerImpl : public DBusThreadManager {
// static
void DBusThreadManager::Initialize() {
- // Ignore Initialize() if we set a test DBusThreadManager.
- if (g_dbus_thread_manager_set_for_testing)
- return;
// If we initialize DBusThreadManager twice we may also be shutting it down
// early; do not allow that.
CHECK(g_dbus_thread_manager == NULL);
+ if (g_dbus_thread_manager_for_testing) {
+ g_dbus_thread_manager = g_dbus_thread_manager_for_testing;
+ InitializeClients();
+ VLOG(1) << "DBusThreadManager initialized with test implementation";
+ return;
+ }
// Determine whether we use stub or real client implementations.
if (base::SysInfo::IsRunningOnChromeOS()) {
g_dbus_thread_manager = new DBusThreadManagerImpl;
@@ -333,21 +336,22 @@ void DBusThreadManager::Initialize() {
VLOG(1) << "DBusThreadManager initialized for ChromeOS";
} else {
InitializeWithStub();
- return;
}
}
// static
+void DBusThreadManager::SetInstanceForTesting(
+ DBusThreadManager* dbus_thread_manager) {
+ CHECK(!g_dbus_thread_manager);
+ CHECK(!g_dbus_thread_manager_for_testing);
+ g_dbus_thread_manager_for_testing = dbus_thread_manager;
+}
+
+// static
void DBusThreadManager::InitializeForTesting(
DBusThreadManager* dbus_thread_manager) {
- // If we initialize DBusThreadManager twice we may also be shutting it down
- // early; do not allow that.
- CHECK(g_dbus_thread_manager == NULL);
- CHECK(dbus_thread_manager);
- g_dbus_thread_manager = dbus_thread_manager;
- g_dbus_thread_manager_set_for_testing = true;
- InitializeClients();
- VLOG(1) << "DBusThreadManager initialized with test implementation";
+ SetInstanceForTesting(dbus_thread_manager);
+ Initialize();
}
// static
@@ -372,9 +376,10 @@ bool DBusThreadManager::IsInitialized() {
void DBusThreadManager::Shutdown() {
// If we called InitializeForTesting, this may get called more than once.
// Ensure that we only shutdown DBusThreadManager once.
- CHECK(g_dbus_thread_manager || g_dbus_thread_manager_set_for_testing);
+ CHECK(g_dbus_thread_manager || g_dbus_thread_manager_for_testing);
DBusThreadManager* dbus_thread_manager = g_dbus_thread_manager;
g_dbus_thread_manager = NULL;
+ g_dbus_thread_manager_for_testing = NULL;
delete dbus_thread_manager;
VLOG(1) << "DBusThreadManager Shutdown completed";
}
@@ -389,9 +394,9 @@ DBusThreadManager::~DBusThreadManager() {
return; // Called form Shutdown() or local test instance.
// There should never be both a global instance and a local instance.
CHECK(this == g_dbus_thread_manager);
- if (g_dbus_thread_manager_set_for_testing) {
+ if (g_dbus_thread_manager_for_testing) {
g_dbus_thread_manager = NULL;
- g_dbus_thread_manager_set_for_testing = false;
+ g_dbus_thread_manager_for_testing = NULL;
VLOG(1) << "DBusThreadManager destroyed";
} else {
LOG(FATAL) << "~DBusThreadManager() called outside of Shutdown()";
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h
index c980b27..c36ddc3 100644
--- a/chromeos/dbus/dbus_thread_manager.h
+++ b/chromeos/dbus/dbus_thread_manager.h
@@ -83,10 +83,18 @@ class CHROMEOS_EXPORT DBusThreadManager {
// making it a Singleton, to ensure clean startup and shutdown.
static void Initialize();
- // Similar to Initialize(), but can inject an alternative
- // DBusThreadManager such as MockDBusThreadManager for testing.
- // The injected object will be owned by the internal pointer and deleted
- // by Shutdown().
+ // Sets an alternative DBusThreadManager such as MockDBusThreadManager
+ // to be used in |Initialize()| for testing. Tests that call
+ // DBusThreadManager::Initialize() (such as browser_tests and
+ // interactive_ui_tests) should use this instead of calling
+ // |InitiailzeForTesting|. The injected object will be owned by the
+ // internal pointer and deleted by Shutdown().
+ static void SetInstanceForTesting(DBusThreadManager* dbus_thread_manager);
+
+ // Similar to Initialize(), but injects an alternative
+ // DBusThreadManager using SetInstanceForTest first. The injected
+ // object will be owned by the internal pointer and deleted by
+ // Shutdown().
static void InitializeForTesting(DBusThreadManager* dbus_thread_manager);
// Initialize with stub implementations for tests based on stubs.
diff --git a/content/browser/renderer_host/render_sandbox_host_linux.cc b/content/browser/renderer_host/render_sandbox_host_linux.cc
index a018043..d17b1ca 100644
--- a/content/browser/renderer_host/render_sandbox_host_linux.cc
+++ b/content/browser/renderer_host/render_sandbox_host_linux.cc
@@ -709,10 +709,9 @@ void RenderSandboxHostLinux::Init(const std::string& sandbox_path) {
childs_lifeline_fd_ = pipefds[1];
// We need to be monothreaded before we fork().
-#if !defined(TOOLKIT_GTK) && !defined(OS_CHROMEOS)
+#if !defined(TOOLKIT_GTK)
// Exclude gtk port as TestSuite in base/tests/test_suite.cc is calling
// gtk_init.
- // Exclude ChromeOS because KioskTest spawns EmbeddedTestServer.
// TODO(oshima): Remove ifdef when above issues are resolved.
DCHECK_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle()));
#endif
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index 871c271..5587180 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -216,9 +216,7 @@ void BrowserTestBase::SetUp() {
rule_based_resolver_->AddSimulatedFailure("wpad");
net::ScopedDefaultHostResolverProc scoped_local_host_resolver_proc(
rule_based_resolver_.get());
-
SetUpInProcessBrowserTestFixture();
-
MainFunctionParams params(*command_line);
params.ui_task =
new base::Closure(
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc
index 3d246d1..aacecd2 100644
--- a/net/test/embedded_test_server/embedded_test_server.cc
+++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -99,6 +99,10 @@ HttpListenSocket::~HttpListenSocket() {
DCHECK(thread_checker_.CalledOnValidThread());
}
+void HttpListenSocket::DetachFromThread() {
+ thread_checker_.DetachFromThread();
+}
+
EmbeddedTestServer::EmbeddedTestServer()
: port_(-1),
weak_factory_(this) {
@@ -114,21 +118,28 @@ EmbeddedTestServer::~EmbeddedTestServer() {
}
bool EmbeddedTestServer::InitializeAndWaitUntilReady() {
- base::Thread::Options thread_options;
- thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
- io_thread_.reset(new base::Thread("EmbeddedTestServer io thread"));
- CHECK(io_thread_->StartWithOptions(thread_options));
-
+ StartThread();
DCHECK(thread_checker_.CalledOnValidThread());
-
if (!PostTaskToIOThreadAndWait(base::Bind(
&EmbeddedTestServer::InitializeOnIOThread, base::Unretained(this)))) {
return false;
}
-
return Started() && base_url_.is_valid();
}
+void EmbeddedTestServer::StopThread() {
+ io_thread_->Stop();
+ io_thread_.reset();
+ thread_checker_.DetachFromThread();
+ listen_socket_->DetachFromThread();
+}
+
+void EmbeddedTestServer::RestartThreadAndListen() {
+ StartThread();
+ CHECK(PostTaskToIOThreadAndWait(base::Bind(
+ &EmbeddedTestServer::ListenOnIOThread, base::Unretained(this))));
+}
+
bool EmbeddedTestServer::ShutdownAndWaitUntilComplete() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -136,6 +147,14 @@ bool EmbeddedTestServer::ShutdownAndWaitUntilComplete() {
&EmbeddedTestServer::ShutdownOnIOThread, base::Unretained(this)));
}
+void EmbeddedTestServer::StartThread() {
+ DCHECK(!io_thread_.get());
+ base::Thread::Options thread_options;
+ thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
+ io_thread_.reset(new base::Thread("EmbeddedTestServer io thread"));
+ CHECK(io_thread_->StartWithOptions(thread_options));
+}
+
void EmbeddedTestServer::InitializeOnIOThread() {
DCHECK(io_thread_->message_loop_proxy()->BelongsToCurrentThread());
DCHECK(!Started());
@@ -157,6 +176,12 @@ void EmbeddedTestServer::InitializeOnIOThread() {
}
}
+void EmbeddedTestServer::ListenOnIOThread() {
+ DCHECK(io_thread_->message_loop_proxy()->BelongsToCurrentThread());
+ DCHECK(Started());
+ listen_socket_->Listen();
+}
+
void EmbeddedTestServer::ShutdownOnIOThread() {
DCHECK(io_thread_->message_loop_proxy()->BelongsToCurrentThread());
diff --git a/net/test/embedded_test_server/embedded_test_server.h b/net/test/embedded_test_server/embedded_test_server.h
index d5300b4..5600e0f 100644
--- a/net/test/embedded_test_server/embedded_test_server.h
+++ b/net/test/embedded_test_server/embedded_test_server.h
@@ -39,6 +39,10 @@ class HttpListenSocket : public TCPListenSocket {
virtual void Listen();
private:
+ friend class EmbeddedTestServer;
+
+ // Detaches the current from |thread_checker_|.
+ void DetachFromThread();
base::ThreadChecker thread_checker_;
};
@@ -48,18 +52,10 @@ class HttpListenSocket : public TCPListenSocket {
// it assumes that the request syntax is correct. It *does not* support
// a Chunked Transfer Encoding.
//
-// The common use case is below:
-//
-// base::Thread io_thread_;
-// scoped_ptr<EmbeddedTestServer> test_server_;
+// The common use case for unit tests is below:
//
// void SetUp() {
-// base::Thread::Options thread_options;
-// thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
-// ASSERT_TRUE(io_thread_.StartWithOptions(thread_options));
-//
-// test_server_.reset(
-// new EmbeddedTestServer(io_thread_.message_loop_proxy()));
+// test_server_.reset(new EmbeddedTestServer());
// ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
// test_server_->RegisterRequestHandler(
// base::Bind(&FooTest::HandleRequest, base::Unretained(this)));
@@ -77,6 +73,24 @@ class HttpListenSocket : public TCPListenSocket {
// return http_response.Pass();
// }
//
+// For a test that spawns another process such as browser_tests, you
+// need to stop the server's thread so that there is no no other
+// threads running while spawning the process. To do so, please follow
+// the following example:
+//
+// void SetUp() {
+// test_server_.reset(new EmbeddedTestServer());
+// // EmbeddedTestServer spawns a thread to initialize socket.
+// // Stop the thread in preparation for fork and exec.
+// test_server_->StopThread();
+// ...
+// InProcessBrowserTest::SetUp();
+// }
+//
+// void SetUpOnMainThread() {
+// test_server_->RestartThreadAndListen();
+// }
+//
class EmbeddedTestServer : public StreamListenSocket::Delegate {
public:
typedef base::Callback<scoped_ptr<HttpResponse>(
@@ -122,10 +136,19 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate {
// on UI thread.
void RegisterRequestHandler(const HandleRequestCallback& callback);
+ // Stops IO thread that handles http requests.
+ void StopThread();
+
+ // Restarts IO thread and listen on the socket.
+ void RestartThreadAndListen();
+
private:
+ void StartThread();
+
// Initializes and starts the server. If initialization succeeds, Starts()
// will return true.
void InitializeOnIOThread();
+ void ListenOnIOThread();
// Shuts down the server.
void ShutdownOnIOThread();