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 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 base::file_handle_mapping_vector AutomationProxy::fds_to_map() const { | 442 base::file_handle_mapping_vector AutomationProxy::fds_to_map() const { |
442 base::file_handle_mapping_vector map; | 443 base::file_handle_mapping_vector map; |
443 const int ipcfd = channel_->GetClientFileDescriptor(); | 444 const int ipcfd = channel_->GetClientFileDescriptor(); |
444 if (ipcfd > -1) | 445 if (ipcfd > -1) |
445 map.push_back(std::make_pair(ipcfd, kPrimaryIPCChannel + 3)); | 446 map.push_back(std::make_pair(ipcfd, kPrimaryIPCChannel + 3)); |
446 return map; | 447 return map; |
447 } | 448 } |
448 #endif // defined(OS_POSIX) | 449 #endif // defined(OS_POSIX) |
449 | 450 |
450 bool AutomationProxy::Send(IPC::Message* message) { | 451 bool AutomationProxy::Send(IPC::Message* message) { |
| 452 return Send(message, |
| 453 action_timeout_.InMilliseconds()); |
| 454 } |
| 455 |
| 456 bool AutomationProxy::Send(IPC::Message* message, int timeout_ms) { |
451 if (!channel_.get()) { | 457 if (!channel_.get()) { |
452 LOG(ERROR) << "Automation channel has been closed; dropping message!"; | 458 LOG(ERROR) << "Automation channel has been closed; dropping message!"; |
453 delete message; | 459 delete message; |
454 return false; | 460 return false; |
455 } | 461 } |
456 | 462 |
457 bool success = channel_->SendWithTimeout(message, | 463 bool success = channel_->SendWithTimeout(message, timeout_ms); |
458 command_execution_timeout_ms()); | |
459 | 464 |
460 if (!success && disconnect_on_failure_) { | 465 if (!success && disconnect_on_failure_) { |
461 // Send failed (possibly due to a timeout). Browser is likely in a weird | 466 // Send failed (possibly due to a timeout). Browser is likely in a weird |
462 // state, and further IPC requests are extremely likely to fail (possibly | 467 // state, and further IPC requests are extremely likely to fail (possibly |
463 // timeout, which would make tests slower). Disconnect the channel now | 468 // timeout, which would make tests slower). Disconnect the channel now |
464 // to avoid the slowness. | 469 // to avoid the slowness. |
465 LOG(ERROR) << "Disconnecting channel after error!"; | 470 LOG(ERROR) << "Disconnecting channel after error!"; |
466 Disconnect(); | 471 Disconnect(); |
467 } | 472 } |
468 | 473 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 // If message sending unsuccessful or test failed, return false. | 552 // If message sending unsuccessful or test failed, return false. |
548 return sent && success; | 553 return sent && success; |
549 } | 554 } |
550 #endif | 555 #endif |
551 | 556 |
552 bool AutomationProxy::ResetToDefaultTheme() { | 557 bool AutomationProxy::ResetToDefaultTheme() { |
553 return Send(new AutomationMsg_ResetToDefaultTheme()); | 558 return Send(new AutomationMsg_ResetToDefaultTheme()); |
554 } | 559 } |
555 | 560 |
556 bool AutomationProxy::SendJSONRequest(const std::string& request, | 561 bool AutomationProxy::SendJSONRequest(const std::string& request, |
| 562 int timeout_ms, |
557 std::string* response) { | 563 std::string* response) { |
558 bool result = false; | 564 bool result = false; |
559 if (!SendAutomationJSONRequest(this, request, response, &result)) | 565 if (!SendAutomationJSONRequest(this, request, timeout_ms, response, &result)) |
560 return false; | 566 return false; |
561 return result; | 567 return result; |
562 } | 568 } |
OLD | NEW |