Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Create a service process that uses a Mock to respond to the browser in order | 5 // Create a service process that uses a Mock to respond to the browser in order |
| 6 // to test launching the browser using the cloud print policy check command | 6 // to test launching the browser using the cloud print policy check command |
| 7 // line switch. | 7 // line switch. |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/process_util.h" | 12 #include "base/process_util.h" |
| 13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 14 #include "base/test/multiprocess_test.h" | 14 #include "base/test/multiprocess_test.h" |
| 15 #include "base/test/test_timeouts.h" | 15 #include "base/test/test_timeouts.h" |
| 16 #include "base/time.h" | 16 #include "base/time.h" |
| 17 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" | 17 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" |
| 18 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory. h" | 18 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory. h" |
| 19 #include "chrome/browser/profiles/profile_keyed_service.h" | 19 #include "chrome/browser/profiles/profile_keyed_service.h" |
| 20 #include "chrome/browser/service/service_process_control.h" | 20 #include "chrome/browser/service/service_process_control.h" |
| 21 #include "chrome/browser/ui/browser_init.h" | 21 #include "chrome/browser/ui/browser_init.h" |
| 22 #include "chrome/common/chrome_notification_types.h" | |
| 23 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
| 24 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
| 25 #include "chrome/common/service_messages.h" | 24 #include "chrome/common/service_messages.h" |
| 26 #include "chrome/common/service_process_util.h" | 25 #include "chrome/common/service_process_util.h" |
| 27 #include "chrome/service/service_ipc_server.h" | 26 #include "chrome/service/service_ipc_server.h" |
| 28 #include "chrome/service/service_process.h" | 27 #include "chrome/service/service_process.h" |
| 29 #include "chrome/test/base/test_launcher_utils.h" | 28 #include "chrome/test/base/test_launcher_utils.h" |
| 30 #include "chrome/test/base/testing_browser_process.h" | 29 #include "chrome/test/base/testing_browser_process.h" |
| 31 #include "chrome/test/base/testing_pref_service.h" | 30 #include "chrome/test/base/testing_pref_service.h" |
| 32 #include "chrome/test/base/testing_profile.h" | 31 #include "chrome/test/base/testing_profile.h" |
| 33 #include "chrome/test/base/testing_profile_manager.h" | 32 #include "chrome/test/base/testing_profile_manager.h" |
| 34 #include "chrome/test/base/ui_test_utils.h" | 33 #include "chrome/test/base/ui_test_utils.h" |
| 35 #include "content/public/browser/notification_service.h" | 34 #include "content/public/browser/notification_service.h" |
| 36 #include "content/test/test_browser_thread.h" | 35 #include "content/test/test_browser_thread.h" |
| 37 #include "ipc/ipc_descriptors.h" | 36 #include "ipc/ipc_descriptors.h" |
| 38 #include "ipc/ipc_switches.h" | 37 #include "ipc/ipc_switches.h" |
| 39 #include "testing/gmock/include/gmock/gmock.h" | 38 #include "testing/gmock/include/gmock/gmock.h" |
| 40 #include "testing/gtest/include/gtest/gtest.h" | 39 #include "testing/gtest/include/gtest/gtest.h" |
| 41 #include "testing/multiprocess_func_list.h" | 40 #include "testing/multiprocess_func_list.h" |
| 42 | 41 |
| 42 #if defined(OS_MACOSX) | |
| 43 #include "chrome/common/mac/mock_launchd.h" | |
| 44 #endif | |
| 43 #if defined(OS_POSIX) | 45 #if defined(OS_POSIX) |
| 44 #include "base/global_descriptors_posix.h" | 46 #include "base/global_descriptors_posix.h" |
| 45 #endif | 47 #endif |
| 46 | 48 |
| 47 using ::testing::AnyNumber; | 49 using ::testing::AnyNumber; |
| 48 using ::testing::Assign; | 50 using ::testing::Assign; |
| 49 using ::testing::AtLeast; | 51 using ::testing::AtLeast; |
| 50 using ::testing::DoAll; | 52 using ::testing::DoAll; |
| 51 using ::testing::Invoke; | 53 using ::testing::Invoke; |
| 52 using ::testing::Mock; | 54 using ::testing::Mock; |
| 53 using ::testing::Property; | 55 using ::testing::Property; |
| 54 using ::testing::Return; | 56 using ::testing::Return; |
| 55 using ::testing::WithoutArgs; | 57 using ::testing::WithoutArgs; |
| 56 using ::testing::_; | 58 using ::testing::_; |
| 57 | 59 |
| 58 namespace { | 60 namespace { |
| 59 | 61 |
| 62 #if defined(OS_MACOSX) | |
| 63 const char kTestExecutablePath[] = "test-executable-path"; | |
| 64 #endif | |
| 65 | |
| 60 bool g_good_shutdown = false; | 66 bool g_good_shutdown = false; |
| 61 | 67 |
| 62 void ShutdownTask() { | 68 void ShutdownTask() { |
| 63 g_good_shutdown = true; | 69 g_good_shutdown = true; |
| 64 g_service_process->Shutdown(); | 70 g_service_process->Shutdown(); |
| 65 } | 71 } |
| 66 | 72 |
| 67 class TestStartupClientChannelListener : public IPC::Channel::Listener { | 73 class TestStartupClientChannelListener : public IPC::Channel::Listener { |
| 68 public: | 74 public: |
| 69 virtual bool OnMessageReceived(const IPC::Message& message) { return false; } | 75 virtual bool OnMessageReceived(const IPC::Message& message) { return false; } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 return true; | 185 return true; |
| 180 } | 186 } |
| 181 | 187 |
| 182 typedef base::Callback<void(MockServiceIPCServer* server)> | 188 typedef base::Callback<void(MockServiceIPCServer* server)> |
| 183 SetExpectationsCallback; | 189 SetExpectationsCallback; |
| 184 | 190 |
| 185 int CloudPrintMockService_Main(SetExpectationsCallback set_expectations) { | 191 int CloudPrintMockService_Main(SetExpectationsCallback set_expectations) { |
| 186 MessageLoopForUI main_message_loop; | 192 MessageLoopForUI main_message_loop; |
| 187 main_message_loop.set_thread_name("Main Thread"); | 193 main_message_loop.set_thread_name("Main Thread"); |
| 188 | 194 |
| 195 #if defined(OS_MACOSX) | |
| 196 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
| 197 FilePath executable_path = cl->GetSwitchValuePath(kTestExecutablePath); | |
|
Albert Bodenhamer
2012/01/20 20:34:19
I've seen crashes resulting from calling GetSwitch
Scott Byer
2012/01/20 23:13:37
Added an error return instead, though I'm surprise
| |
| 198 EXPECT_NE(std::string(), executable_path.value()); | |
|
Mark Mentovai
2012/01/20 20:41:35
EXPECT_FALSE(executable_path.value().empty()) is m
Scott Byer
2012/01/20 23:13:37
Done.
| |
| 199 MockLaunchd mock_launchd(executable_path, &main_message_loop, true, true); | |
| 200 Launchd::ScopedInstance use_mock(&mock_launchd); | |
| 201 #endif | |
| 202 | |
| 189 ServiceProcessState* state(new ServiceProcessState); | 203 ServiceProcessState* state(new ServiceProcessState); |
| 190 EXPECT_TRUE(state->Initialize()); | 204 bool service_process_state_initialized = state->Initialize(); |
| 205 EXPECT_TRUE(service_process_state_initialized); | |
| 206 if (!service_process_state_initialized) | |
| 207 return -1; | |
|
Albert Bodenhamer
2012/01/20 20:34:19
What is the significance of -1 here?
Scott Byer
2012/01/20 23:13:37
Added a comment at the top of the routine; renumbe
| |
| 191 | 208 |
| 192 TestServiceProcess service_process; | 209 TestServiceProcess service_process; |
| 193 EXPECT_EQ(&service_process, g_service_process); | 210 EXPECT_EQ(&service_process, g_service_process); |
| 194 | 211 |
| 195 // Takes ownership of the pointer, but we can use it since we have the same | 212 // Takes ownership of the pointer, but we can use it since we have the same |
| 196 // lifetime. | 213 // lifetime. |
| 197 EXPECT_TRUE(service_process.Initialize(&main_message_loop, state)); | 214 EXPECT_TRUE(service_process.Initialize(&main_message_loop, state)); |
| 198 | 215 |
| 199 MockServiceIPCServer server(state->GetServiceProcessChannel()); | 216 MockServiceIPCServer server(state->GetServiceProcessChannel()); |
| 200 | 217 |
| 201 // Here is where the expectations/mock responses need to be set up. | 218 // Here is where the expectations/mock responses need to be set up. |
| 202 set_expectations.Run(&server); | 219 set_expectations.Run(&server); |
| 203 | 220 |
| 204 EXPECT_TRUE(server.Init()); | 221 EXPECT_TRUE(server.Init()); |
| 205 EXPECT_TRUE(state->SignalReady(service_process.IOMessageLoopProxy(), | 222 EXPECT_TRUE(state->SignalReady(service_process.IOMessageLoopProxy(), |
| 206 base::Bind(&ShutdownTask))); | 223 base::Bind(&ShutdownTask))); |
| 224 #if defined(OS_MACOSX) | |
| 225 mock_launchd.SignalReady(); | |
| 226 #endif | |
| 207 | 227 |
| 208 // Connect up the parent/child IPC channel to signal that the test can | 228 // Connect up the parent/child IPC channel to signal that the test can |
| 209 // continue. | 229 // continue. |
| 210 TestStartupClientChannelListener listener; | 230 TestStartupClientChannelListener listener; |
| 211 EXPECT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch( | 231 EXPECT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch( |
| 212 switches::kProcessChannelID)); | 232 switches::kProcessChannelID)); |
| 213 std::string startup_channel_name = | 233 std::string startup_channel_name = |
| 214 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 234 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 215 switches::kProcessChannelID); | 235 switches::kProcessChannelID); |
| 216 scoped_ptr<IPC::ChannelProxy> startup_channel; | 236 scoped_ptr<IPC::ChannelProxy> startup_channel; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 } | 298 } |
| 279 | 299 |
| 280 protected: | 300 protected: |
| 281 MessageLoopForUI message_loop_; | 301 MessageLoopForUI message_loop_; |
| 282 content::TestBrowserThread ui_thread_; | 302 content::TestBrowserThread ui_thread_; |
| 283 base::Thread io_thread_; | 303 base::Thread io_thread_; |
| 284 | 304 |
| 285 std::string startup_channel_id_; | 305 std::string startup_channel_id_; |
| 286 scoped_ptr<IPC::ChannelProxy> startup_channel_; | 306 scoped_ptr<IPC::ChannelProxy> startup_channel_; |
| 287 | 307 |
| 308 #if defined(OS_MACOSX) | |
| 309 ScopedTempDir temp_dir_; | |
| 310 FilePath executable_path_, bundle_path_; | |
| 311 scoped_ptr<MockLaunchd> mock_launchd_; | |
| 312 scoped_ptr<Launchd::ScopedInstance> scoped_launchd_instance_; | |
| 313 #endif | |
| 314 | |
| 288 private: | 315 private: |
| 289 class WindowedChannelConnectionObserver { | 316 class WindowedChannelConnectionObserver { |
| 290 public: | 317 public: |
| 291 WindowedChannelConnectionObserver() | 318 WindowedChannelConnectionObserver() |
| 292 : seen_(false), | 319 : seen_(false), |
| 293 running_(false) { } | 320 running_(false) { } |
| 294 | 321 |
| 295 void Wait() { | 322 void Wait() { |
| 296 if (seen_) | 323 if (seen_) |
| 297 return; | 324 return; |
| 298 running_ = true; | 325 running_ = true; |
| 299 ui_test_utils::RunMessageLoop(); | 326 ui_test_utils::RunMessageLoop(); |
| 300 } | 327 } |
| 301 | 328 |
| 302 void Notify() { | 329 void Notify() { |
| 303 seen_ = true; | 330 seen_ = true; |
| 304 if (running_) | 331 if (running_) |
| 305 MessageLoopForUI::current()->Quit(); | 332 MessageLoopForUI::current()->Quit(); |
| 306 } | 333 } |
| 307 | 334 |
| 308 private: | 335 private: |
| 309 bool seen_; | 336 bool seen_; |
| 310 bool running_; | 337 bool running_; |
| 311 }; | 338 }; |
| 312 | 339 |
| 313 WindowedChannelConnectionObserver observer_; | 340 WindowedChannelConnectionObserver observer_; |
| 314 }; | 341 }; |
| 315 | 342 |
| 316 | |
| 317 CloudPrintProxyPolicyStartupTest::CloudPrintProxyPolicyStartupTest() | 343 CloudPrintProxyPolicyStartupTest::CloudPrintProxyPolicyStartupTest() |
| 318 : ui_thread_(content::BrowserThread::UI, &message_loop_), | 344 : ui_thread_(content::BrowserThread::UI, &message_loop_), |
| 319 io_thread_("CloudPrintProxyPolicyTestThread") { | 345 io_thread_("CloudPrintProxyPolicyTestThread") { |
| 320 } | 346 } |
| 321 | 347 |
| 322 CloudPrintProxyPolicyStartupTest::~CloudPrintProxyPolicyStartupTest() { | 348 CloudPrintProxyPolicyStartupTest::~CloudPrintProxyPolicyStartupTest() { |
| 323 } | 349 } |
| 324 | 350 |
| 325 void CloudPrintProxyPolicyStartupTest::SetUp() { | 351 void CloudPrintProxyPolicyStartupTest::SetUp() { |
| 326 base::Thread::Options options(MessageLoop::TYPE_IO, 0); | 352 base::Thread::Options options(MessageLoop::TYPE_IO, 0); |
| 327 ASSERT_TRUE(io_thread_.StartWithOptions(options)); | 353 ASSERT_TRUE(io_thread_.StartWithOptions(options)); |
| 354 | |
| 355 #if defined(OS_MACOSX) | |
| 356 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
| 357 EXPECT_TRUE(MockLaunchd::MakeABundle(temp_dir_.path(), | |
| 358 "CloudPrintProxyTest", | |
| 359 &bundle_path_, | |
| 360 &executable_path_)); | |
| 361 mock_launchd_.reset(new MockLaunchd(executable_path_, &message_loop_, | |
| 362 true, false)); | |
| 363 scoped_launchd_instance_.reset( | |
| 364 new Launchd::ScopedInstance(mock_launchd_.get())); | |
| 365 #endif | |
| 328 } | 366 } |
| 329 | 367 |
| 330 base::ProcessHandle CloudPrintProxyPolicyStartupTest::Launch( | 368 base::ProcessHandle CloudPrintProxyPolicyStartupTest::Launch( |
| 331 const std::string& name) { | 369 const std::string& name) { |
| 332 EXPECT_FALSE(CheckServiceProcessReady()); | 370 EXPECT_FALSE(CheckServiceProcessReady()); |
| 333 | 371 |
| 334 startup_channel_id_ = | 372 startup_channel_id_ = |
| 335 base::StringPrintf("%d.%p.%d", | 373 base::StringPrintf("%d.%p.%d", |
| 336 base::GetCurrentProcId(), this, | 374 base::GetCurrentProcId(), this, |
| 337 base::RandInt(0, std::numeric_limits<int>::max())); | 375 base::RandInt(0, std::numeric_limits<int>::max())); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 | 418 |
| 381 void CloudPrintProxyPolicyStartupTest::OnChannelConnected(int32 peer_pid) { | 419 void CloudPrintProxyPolicyStartupTest::OnChannelConnected(int32 peer_pid) { |
| 382 observer_.Notify(); | 420 observer_.Notify(); |
| 383 } | 421 } |
| 384 | 422 |
| 385 CommandLine CloudPrintProxyPolicyStartupTest::MakeCmdLine( | 423 CommandLine CloudPrintProxyPolicyStartupTest::MakeCmdLine( |
| 386 const std::string& procname, | 424 const std::string& procname, |
| 387 bool debug_on_start) { | 425 bool debug_on_start) { |
| 388 CommandLine cl = MultiProcessTest::MakeCmdLine(procname, debug_on_start); | 426 CommandLine cl = MultiProcessTest::MakeCmdLine(procname, debug_on_start); |
| 389 cl.AppendSwitchASCII(switches::kProcessChannelID, startup_channel_id_); | 427 cl.AppendSwitchASCII(switches::kProcessChannelID, startup_channel_id_); |
| 428 #if defined(OS_MACOSX) | |
| 429 cl.AppendSwitchASCII(kTestExecutablePath, executable_path_.value()); | |
| 430 #endif | |
| 390 return cl; | 431 return cl; |
| 391 } | 432 } |
| 392 | 433 |
| 393 TEST_F(CloudPrintProxyPolicyStartupTest, StartAndShutdown) { | 434 TEST_F(CloudPrintProxyPolicyStartupTest, StartAndShutdown) { |
| 394 base::ProcessHandle handle = | 435 base::ProcessHandle handle = |
| 395 Launch("CloudPrintMockService_StartEnabledWaitForQuit"); | 436 Launch("CloudPrintMockService_StartEnabledWaitForQuit"); |
| 396 WaitForConnect(); | 437 WaitForConnect(); |
| 397 ShutdownAndWaitForExitWithTimeout(handle); | 438 ShutdownAndWaitForExitWithTimeout(handle); |
| 398 } | 439 } |
| 399 | 440 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 479 // No expectations on run_loop being true here; that would be a race | 520 // No expectations on run_loop being true here; that would be a race |
| 480 // condition. | 521 // condition. |
| 481 if (run_loop) | 522 if (run_loop) |
| 482 MessageLoop::current()->Run(); | 523 MessageLoop::current()->Run(); |
| 483 | 524 |
| 484 EXPECT_EQ("", prefs->GetString(prefs::kCloudPrintEmail)); | 525 EXPECT_EQ("", prefs->GetString(prefs::kCloudPrintEmail)); |
| 485 | 526 |
| 486 ShutdownAndWaitForExitWithTimeout(handle); | 527 ShutdownAndWaitForExitWithTimeout(handle); |
| 487 profile_manager.DeleteTestingProfile("StartBrowserWithPolicy"); | 528 profile_manager.DeleteTestingProfile("StartBrowserWithPolicy"); |
| 488 } | 529 } |
| OLD | NEW |