| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "chrome/test/automation/automation_proxy.h" | 5 #include "chrome/test/automation/automation_proxy.h" |
| 6 | 6 |
| 7 #include <gtest/gtest.h> | 7 #include <gtest/gtest.h> |
| 8 | 8 |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 14 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" |
| 15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 16 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
| 17 #include "base/test/test_timeouts.h" |
| 17 #include "chrome/common/automation_constants.h" | 18 #include "chrome/common/automation_constants.h" |
| 18 #include "chrome/common/automation_messages.h" | 19 #include "chrome/common/automation_messages.h" |
| 19 #include "chrome/common/chrome_version_info.h" | 20 #include "chrome/common/chrome_version_info.h" |
| 20 #include "chrome/test/automation/automation_json_requests.h" | 21 #include "chrome/test/automation/automation_json_requests.h" |
| 21 #include "chrome/test/automation/browser_proxy.h" | 22 #include "chrome/test/automation/browser_proxy.h" |
| 22 #include "chrome/test/automation/extension_proxy.h" | 23 #include "chrome/test/automation/extension_proxy.h" |
| 23 #include "chrome/test/automation/tab_proxy.h" | 24 #include "chrome/test/automation/tab_proxy.h" |
| 24 #include "chrome/test/automation/window_proxy.h" | 25 #include "chrome/test/automation/window_proxy.h" |
| 25 #include "ipc/ipc_descriptors.h" | 26 #include "ipc/ipc_descriptors.h" |
| 26 #if defined(OS_WIN) | 27 #if defined(OS_WIN) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 server_->SignalAppLaunch(server_version); | 84 server_->SignalAppLaunch(server_version); |
| 84 } | 85 } |
| 85 | 86 |
| 86 private: | 87 private: |
| 87 AutomationProxy* server_; | 88 AutomationProxy* server_; |
| 88 }; | 89 }; |
| 89 | 90 |
| 90 } // anonymous namespace | 91 } // anonymous namespace |
| 91 | 92 |
| 92 | 93 |
| 93 AutomationProxy::AutomationProxy(int command_execution_timeout_ms, | 94 AutomationProxy::AutomationProxy(int action_timeout_ms, |
| 94 bool disconnect_on_failure) | 95 bool disconnect_on_failure) |
| 95 : app_launched_(true, false), | 96 : app_launched_(true, false), |
| 96 initial_loads_complete_(true, false), | 97 initial_loads_complete_(true, false), |
| 97 new_tab_ui_load_complete_(true, false), | 98 new_tab_ui_load_complete_(true, false), |
| 98 shutdown_event_(new base::WaitableEvent(true, false)), | 99 shutdown_event_(new base::WaitableEvent(true, false)), |
| 99 app_launch_signaled_(0), | 100 app_launch_signaled_(0), |
| 100 perform_version_check_(false), | 101 perform_version_check_(false), |
| 101 disconnect_on_failure_(disconnect_on_failure), | 102 disconnect_on_failure_(disconnect_on_failure), |
| 102 command_execution_timeout_( | 103 action_timeout_( |
| 103 TimeDelta::FromMilliseconds(command_execution_timeout_ms)), | 104 TimeDelta::FromMilliseconds(action_timeout_ms)), |
| 104 listener_thread_id_(0) { | 105 listener_thread_id_(0) { |
| 105 // base::WaitableEvent::TimedWait() will choke if we give it a negative value. | 106 // base::WaitableEvent::TimedWait() will choke if we give it a negative value. |
| 106 // Zero also seems unreasonable, since we need to wait for IPC, but at | 107 // Zero also seems unreasonable, since we need to wait for IPC, but at |
| 107 // least it is legal... ;-) | 108 // least it is legal... ;-) |
| 108 DCHECK_GE(command_execution_timeout_ms, 0); | 109 DCHECK_GE(action_timeout_ms, 0); |
| 109 listener_thread_id_ = base::PlatformThread::CurrentId(); | 110 listener_thread_id_ = base::PlatformThread::CurrentId(); |
| 110 InitializeHandleTracker(); | 111 InitializeHandleTracker(); |
| 111 InitializeThread(); | 112 InitializeThread(); |
| 112 } | 113 } |
| 113 | 114 |
| 114 AutomationProxy::~AutomationProxy() { | 115 AutomationProxy::~AutomationProxy() { |
| 115 // Destruction order is important. Thread has to outlive the channel and | 116 // Destruction order is important. Thread has to outlive the channel and |
| 116 // tracker has to outlive the thread since we access the tracker inside | 117 // tracker has to outlive the thread since we access the tracker inside |
| 117 // AutomationMessageFilter::OnMessageReceived. | 118 // AutomationMessageFilter::OnMessageReceived. |
| 118 Disconnect(); | 119 Disconnect(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 shutdown_event_.get())); | 163 shutdown_event_.get())); |
| 163 channel_->AddFilter(new AutomationMessageFilter(this)); | 164 channel_->AddFilter(new AutomationMessageFilter(this)); |
| 164 } | 165 } |
| 165 | 166 |
| 166 void AutomationProxy::InitializeHandleTracker() { | 167 void AutomationProxy::InitializeHandleTracker() { |
| 167 tracker_.reset(new AutomationHandleTracker()); | 168 tracker_.reset(new AutomationHandleTracker()); |
| 168 } | 169 } |
| 169 | 170 |
| 170 AutomationLaunchResult AutomationProxy::WaitForAppLaunch() { | 171 AutomationLaunchResult AutomationProxy::WaitForAppLaunch() { |
| 171 AutomationLaunchResult result = AUTOMATION_SUCCESS; | 172 AutomationLaunchResult result = AUTOMATION_SUCCESS; |
| 172 if (app_launched_.TimedWait(command_execution_timeout_)) { | 173 if (app_launched_.TimedWait(action_timeout_)) { |
| 173 if (perform_version_check_) { | 174 if (perform_version_check_) { |
| 174 // Obtain our own version number and compare it to what the automation | 175 // Obtain our own version number and compare it to what the automation |
| 175 // provider sent. | 176 // provider sent. |
| 176 chrome::VersionInfo version_info; | 177 chrome::VersionInfo version_info; |
| 177 DCHECK(version_info.is_valid()); | 178 DCHECK(version_info.is_valid()); |
| 178 | 179 |
| 179 // Note that we use a simple string comparison since we expect the version | 180 // Note that we use a simple string comparison since we expect the version |
| 180 // to be a punctuated numeric string. Consider using base/Version if we | 181 // to be a punctuated numeric string. Consider using base/Version if we |
| 181 // ever need something more complicated here. | 182 // ever need something more complicated here. |
| 182 if (server_version_ != version_info.Version()) { | 183 if (server_version_ != version_info.Version()) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 202 } | 203 } |
| 203 server_version_ = version_string; | 204 server_version_ = version_string; |
| 204 app_launched_.Signal(); | 205 app_launched_.Signal(); |
| 205 } | 206 } |
| 206 | 207 |
| 207 bool AutomationProxy::WaitForProcessLauncherThreadToGoIdle() { | 208 bool AutomationProxy::WaitForProcessLauncherThreadToGoIdle() { |
| 208 return Send(new AutomationMsg_WaitForProcessLauncherThreadToGoIdle()); | 209 return Send(new AutomationMsg_WaitForProcessLauncherThreadToGoIdle()); |
| 209 } | 210 } |
| 210 | 211 |
| 211 bool AutomationProxy::WaitForInitialLoads() { | 212 bool AutomationProxy::WaitForInitialLoads() { |
| 212 return initial_loads_complete_.TimedWait(command_execution_timeout_); | 213 return initial_loads_complete_.TimedWait(action_timeout_); |
| 213 } | 214 } |
| 214 | 215 |
| 215 bool AutomationProxy::WaitForInitialNewTabUILoad(int* load_time) { | 216 bool AutomationProxy::WaitForInitialNewTabUILoad(int* load_time) { |
| 216 if (new_tab_ui_load_complete_.TimedWait(command_execution_timeout_)) { | 217 if (new_tab_ui_load_complete_.TimedWait(action_timeout_)) { |
| 217 *load_time = new_tab_ui_load_time_; | 218 *load_time = new_tab_ui_load_time_; |
| 218 new_tab_ui_load_complete_.Reset(); | 219 new_tab_ui_load_complete_.Reset(); |
| 219 return true; | 220 return true; |
| 220 } | 221 } |
| 221 return false; | 222 return false; |
| 222 } | 223 } |
| 223 | 224 |
| 224 void AutomationProxy::SignalInitialLoads() { | 225 void AutomationProxy::SignalInitialLoads() { |
| 225 initial_loads_complete_.Signal(); | 226 initial_loads_complete_.Signal(); |
| 226 } | 227 } |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 base::file_handle_mapping_vector AutomationProxy::fds_to_map() const { | 437 base::file_handle_mapping_vector AutomationProxy::fds_to_map() const { |
| 437 base::file_handle_mapping_vector map; | 438 base::file_handle_mapping_vector map; |
| 438 const int ipcfd = channel_->GetClientFileDescriptor(); | 439 const int ipcfd = channel_->GetClientFileDescriptor(); |
| 439 if (ipcfd > -1) | 440 if (ipcfd > -1) |
| 440 map.push_back(std::make_pair(ipcfd, kPrimaryIPCChannel + 3)); | 441 map.push_back(std::make_pair(ipcfd, kPrimaryIPCChannel + 3)); |
| 441 return map; | 442 return map; |
| 442 } | 443 } |
| 443 #endif // defined(OS_POSIX) | 444 #endif // defined(OS_POSIX) |
| 444 | 445 |
| 445 bool AutomationProxy::Send(IPC::Message* message) { | 446 bool AutomationProxy::Send(IPC::Message* message) { |
| 447 return Send(message, |
| 448 static_cast<int>(action_timeout_.InMilliseconds())); |
| 449 } |
| 450 |
| 451 bool AutomationProxy::Send(IPC::Message* message, int timeout_ms) { |
| 446 if (!channel_.get()) { | 452 if (!channel_.get()) { |
| 447 LOG(ERROR) << "Automation channel has been closed; dropping message!"; | 453 LOG(ERROR) << "Automation channel has been closed; dropping message!"; |
| 448 delete message; | 454 delete message; |
| 449 return false; | 455 return false; |
| 450 } | 456 } |
| 451 | 457 |
| 452 bool success = channel_->SendWithTimeout(message, | 458 bool success = channel_->SendWithTimeout(message, timeout_ms); |
| 453 command_execution_timeout_ms()); | |
| 454 | 459 |
| 455 if (!success && disconnect_on_failure_) { | 460 if (!success && disconnect_on_failure_) { |
| 456 // Send failed (possibly due to a timeout). Browser is likely in a weird | 461 // Send failed (possibly due to a timeout). Browser is likely in a weird |
| 457 // state, and further IPC requests are extremely likely to fail (possibly | 462 // state, and further IPC requests are extremely likely to fail (possibly |
| 458 // timeout, which would make tests slower). Disconnect the channel now | 463 // timeout, which would make tests slower). Disconnect the channel now |
| 459 // to avoid the slowness. | 464 // to avoid the slowness. |
| 460 LOG(ERROR) << "Disconnecting channel after error!"; | 465 LOG(ERROR) << "Disconnecting channel after error!"; |
| 461 Disconnect(); | 466 Disconnect(); |
| 462 } | 467 } |
| 463 | 468 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 // If message sending unsuccessful or test failed, return false. | 547 // If message sending unsuccessful or test failed, return false. |
| 543 return sent && success; | 548 return sent && success; |
| 544 } | 549 } |
| 545 #endif | 550 #endif |
| 546 | 551 |
| 547 bool AutomationProxy::ResetToDefaultTheme() { | 552 bool AutomationProxy::ResetToDefaultTheme() { |
| 548 return Send(new AutomationMsg_ResetToDefaultTheme()); | 553 return Send(new AutomationMsg_ResetToDefaultTheme()); |
| 549 } | 554 } |
| 550 | 555 |
| 551 bool AutomationProxy::SendJSONRequest(const std::string& request, | 556 bool AutomationProxy::SendJSONRequest(const std::string& request, |
| 557 int timeout_ms, |
| 552 std::string* response) { | 558 std::string* response) { |
| 553 bool result = false; | 559 bool result = false; |
| 554 if (!SendAutomationJSONRequest(this, request, response, &result)) | 560 if (!SendAutomationJSONRequest(this, request, timeout_ms, response, &result)) |
| 555 return false; | 561 return false; |
| 556 return result; | 562 return result; |
| 557 } | 563 } |
| OLD | NEW |