1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file. 4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/basictypes.h" 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/logging.h" 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/message_loop.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/message_loop_proxy.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/synchronization/condition_variable.h" 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/synchronization/lock.h" 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/threading/platform_thread.h" 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/time.h" 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "build/build_config.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/metrics/thread_watcher.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "testing/gtest/include/gtest/gtest.h" 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "testing/platform_test.h" 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenusing base::TimeDelta; 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenusing base::TimeTicks; 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenenum State { 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen INITIALIZED, // Created ThreadWatch object. 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ACTIVATED, // Thread watching activated. 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SENT_PING, // Sent ping message to watched thread. 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RECEIVED_PONG, // Received Pong message. 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DEACTIVATED, // Thread watching de-activated. 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenenum WaitState { 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UNINITIALIZED, 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen STARTED_WAITING, // Start waiting for state_ to change to expected_state. 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen STOPPED_WAITING, // Done with the waiting. 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ALL_DONE, // Done with waiting for STOPPED_WAITING. 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenenum CheckResponseState { 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UNKNOWN, 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SUCCESSFUL, // CheckResponse was successful. 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FAILED, // CheckResponse has failed. 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// This class helps to track and manipulate thread state during tests. This 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// class also has utility method to simulate hanging of watched thread by making 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// the watched thread wait for a very long time by posting a task on watched 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// thread that keeps it busy. It also has an utility method to block running of 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// tests until ThreadWatcher object's post-condition state changes to an 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// expected state. 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenclass CustomThreadWatcher : public ThreadWatcher { 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen public: 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::Lock custom_lock_; 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::ConditionVariable state_changed_; 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State thread_watcher_state_; 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WaitState wait_state_; 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CheckResponseState check_response_state_; 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint64 ping_sent_; 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint64 pong_received_; 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint64 success_response_; 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint64 failed_response_; 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::TimeTicks saved_ping_time_; 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint64 saved_ping_sequence_number_; 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CustomThreadWatcher(const BrowserThread::ID thread_id, 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string thread_name, 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const TimeDelta& sleep_time, 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const TimeDelta& unresponsive_time) 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : ThreadWatcher(thread_id, thread_name, sleep_time, unresponsive_time), 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state_changed_(&custom_lock_), 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen thread_watcher_state_(INITIALIZED), 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen wait_state_(UNINITIALIZED), 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen check_response_state_(UNKNOWN), 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ping_sent_(0), 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pong_received_(0), 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen success_response_(0), 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen failed_response_(0), 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen saved_ping_time_(base::TimeTicks::Now()), 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen saved_ping_sequence_number_(0) { 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State UpdateState(State new_state) { 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State old_state; 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen { 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::AutoLock auto_lock(custom_lock_); 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen old_state = thread_watcher_state_; 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (old_state != DEACTIVATED) 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen thread_watcher_state_ = new_state; 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (new_state == SENT_PING) 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ++ping_sent_; 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (new_state == RECEIVED_PONG) 90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ++pong_received_; 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen saved_ping_time_ = ping_time(); 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen saved_ping_sequence_number_ = ping_sequence_number(); 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state_changed_.Broadcast(); 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return old_state; 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WaitState UpdateWaitState(WaitState new_state) { 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WaitState old_state; 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen { 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::AutoLock auto_lock(custom_lock_); 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen old_state = wait_state_; 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen wait_state_ = new_state; 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state_changed_.Broadcast(); 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return old_state; 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void ActivateThreadWatching() { 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State old_state = UpdateState(ACTIVATED); 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(old_state, INITIALIZED); 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ThreadWatcher::ActivateThreadWatching(); 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void DeActivateThreadWatching() { 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State old_state = UpdateState(DEACTIVATED); 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(old_state == ACTIVATED || old_state == SENT_PING || 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen old_state == RECEIVED_PONG); 119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ThreadWatcher::DeActivateThreadWatching(); 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void PostPingMessage() { 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State old_state = UpdateState(SENT_PING); 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(old_state == ACTIVATED || old_state == RECEIVED_PONG); 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ThreadWatcher::PostPingMessage(); 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void OnPongMessage(uint64 ping_sequence_number) { 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State old_state = UpdateState(RECEIVED_PONG); 130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(old_state == SENT_PING || old_state == DEACTIVATED); 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ThreadWatcher::OnPongMessage(ping_sequence_number); 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool OnCheckResponsiveness(uint64 ping_sequence_number) { 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool responsive = 136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ThreadWatcher::OnCheckResponsiveness(ping_sequence_number); 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen { 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::AutoLock auto_lock(custom_lock_); 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (responsive) { 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ++success_response_; 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen check_response_state_ = SUCCESSFUL; 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ++failed_response_; 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen check_response_state_ = FAILED; 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Broadcast to indicate we have checked responsiveness of the thread that 148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // is watched. 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state_changed_.Broadcast(); 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return responsive; 151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void WaitForWaitStateChange(TimeDelta wait_time, WaitState expected_state) { 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); 155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeTicks end_time = TimeTicks::Now() + wait_time; 156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen { 157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::AutoLock auto_lock(custom_lock_); 158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (wait_state_ != expected_state && TimeTicks::Now() < end_time) 159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state_changed_.TimedWait(end_time - TimeTicks::Now()); 160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void VeryLongMethod(TimeDelta wait_time) { 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WaitForWaitStateChange(wait_time, STOPPED_WAITING); 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UpdateWaitState(ALL_DONE); 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State WaitForStateChange(const TimeDelta& wait_time, State expected_state) { 170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UpdateWaitState(STARTED_WAITING); 172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen State exit_state; 174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Keep the thread that is running the tests waiting until ThreadWatcher 175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // object's state changes to the expected_state or until wait_time elapses. 176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (int i = 0; i < 3; ++i) { 177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeTicks end_time = TimeTicks::Now() + wait_time; 178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen { 179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::AutoLock auto_lock(custom_lock_); 180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (thread_watcher_state_ != expected_state && 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeTicks::Now() < end_time) { 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeDelta state_change_wait_time = end_time - TimeTicks::Now(); 183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state_changed_.TimedWait(state_change_wait_time); 184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Capture the thread_watcher_state_ before it changes and return it 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // to the caller. 187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen exit_state = thread_watcher_state_; 188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (exit_state == expected_state) 189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UpdateWaitState(STOPPED_WAITING); 193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return exit_state; 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CheckResponseState WaitForCheckResponse(const TimeDelta& wait_time, 197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CheckResponseState expected_state) { 198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); 199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UpdateWaitState(STARTED_WAITING); 200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CheckResponseState exit_state; 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Keep the thread that is running the tests waiting until ThreadWatcher 203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // object's check_response_state_ changes to the expected_state or until 204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // wait_time elapses. 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (int i = 0; i < 3; ++i) { 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeTicks end_time = TimeTicks::Now() + wait_time; 207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen { 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::AutoLock auto_lock(custom_lock_); 209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (check_response_state_ != expected_state && 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeTicks::Now() < end_time) { 211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeDelta state_change_wait_time = end_time - TimeTicks::Now(); 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state_changed_.TimedWait(state_change_wait_time); 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Capture the check_response_state_ before it changes and return it 215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // to the caller. 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen exit_state = check_response_state_; 217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (exit_state == expected_state) 218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UpdateWaitState(STOPPED_WAITING); 222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return exit_state; 223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 226dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenDISABLE_RUNNABLE_METHOD_REFCOUNT(CustomThreadWatcher); 227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenclass ThreadWatcherTest : public ::testing::Test { 229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen public: 230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static const TimeDelta kSleepTime; 231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static const TimeDelta kUnresponsiveTime; 232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static const BrowserThread::ID io_thread_id; 233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static const std::string io_thread_name; 234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static const BrowserThread::ID webkit_thread_id; 235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static const std::string webkit_thread_name; 236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CustomThreadWatcher* io_watcher_; 237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CustomThreadWatcher* webkit_watcher_; 238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ThreadWatcherTest() { 240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_thread_.reset(new BrowserThread(BrowserThread::WEBKIT)); 241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_thread_.reset(new BrowserThread(BrowserThread::IO)); 242dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen watchdog_thread_.reset(new WatchDogThread()); 243dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_thread_->Start(); 244dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_thread_->Start(); 245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen watchdog_thread_->Start(); 246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Setup the registry for thread watchers. 248dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen thread_watcher_list_ = new ThreadWatcherList(); 249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Create thread watcher object for the IO thread. 251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_ = new CustomThreadWatcher(io_thread_id, io_thread_name, 252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kSleepTime, kUnresponsiveTime); 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Create thread watcher object for the WEBKIT thread. 255dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_watcher_ = new CustomThreadWatcher( 256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_thread_id, webkit_thread_name, kSleepTime, kUnresponsiveTime); 257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ~ThreadWatcherTest() { 260dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ThreadWatcherList::StopWatchingAll(); 261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_ = NULL; 262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_watcher_ = NULL; 263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_thread_.reset(); 264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_thread_.reset(); 265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen watchdog_thread_.reset(); 266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete thread_watcher_list_; 267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 269dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen private: 270dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<BrowserThread> webkit_thread_; 271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<BrowserThread> io_thread_; 272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<WatchDogThread> watchdog_thread_; 273dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ThreadWatcherList* thread_watcher_list_; 274dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Define static constants. 277dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst TimeDelta ThreadWatcherTest::kSleepTime = 278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeDelta::FromMilliseconds(50); 279dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst TimeDelta ThreadWatcherTest::kUnresponsiveTime = 280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeDelta::FromMilliseconds(500); 281dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst BrowserThread::ID ThreadWatcherTest::io_thread_id = BrowserThread::IO; 282dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst std::string ThreadWatcherTest::io_thread_name = "IO"; 283dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst BrowserThread::ID ThreadWatcherTest::webkit_thread_id = 284dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BrowserThread::WEBKIT; 285dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst std::string ThreadWatcherTest::webkit_thread_name = "WEBKIT"; 286dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Test registration. When thread_watcher_list_ goes out of scope after 288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// TearDown, all thread watcher objects will be deleted. 289dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(ThreadWatcherTest, Registration) { 290dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(io_watcher_, ThreadWatcherList::Find(io_thread_id)); 291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(webkit_watcher_, ThreadWatcherList::Find(webkit_thread_id)); 292dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 293dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check ThreadWatcher object has all correct parameters. 294dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(io_thread_id, io_watcher_->thread_id()); 295dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(io_thread_name, io_watcher_->thread_name()); 296dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(kSleepTime, io_watcher_->sleep_time()); 297dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(kUnresponsiveTime, io_watcher_->unresponsive_time()); 298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_FALSE(io_watcher_->active()); 299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 300dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check ThreadWatcher object of watched WEBKIT thread has correct data. 301dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(webkit_thread_id, webkit_watcher_->thread_id()); 302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(webkit_thread_name, webkit_watcher_->thread_name()); 303dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(kSleepTime, webkit_watcher_->sleep_time()); 304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(kUnresponsiveTime, webkit_watcher_->unresponsive_time()); 305dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_FALSE(webkit_watcher_->active()); 306dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 307dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 308dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Test ActivateThreadWatching and DeActivateThreadWatching of IO thread. This 309dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// method also checks that pong message was sent by the watched thread and pong 310dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// message was received by the WatchDogThread. It also checks that 311dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// OnCheckResponsiveness has verified the ping-pong mechanism and the watched 312dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// thread is not hung. 313dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(ThreadWatcherTest, ThreadResponding) { 314dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeTicks time_before_ping = TimeTicks::Now(); 315dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Activate watching IO thread. 316dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 317dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 318dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod(io_watcher_, &ThreadWatcher::ActivateThreadWatching)); 319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 320dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Activate would have started ping/pong messaging. Expect atleast one 321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // ping/pong messaging sequence to happen. 322dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_->WaitForStateChange(kSleepTime + TimeDelta::FromMinutes(1), 323dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RECEIVED_PONG); 324dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(io_watcher_->ping_sent_, static_cast<uint64>(0)); 325dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(io_watcher_->pong_received_, static_cast<uint64>(0)); 326dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(io_watcher_->active()); 327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GE(io_watcher_->saved_ping_time_, time_before_ping); 328dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GE(io_watcher_->saved_ping_sequence_number_, static_cast<uint64>(0)); 329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 330dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Verify watched thread is responding with ping/pong messaging. 331dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_->WaitForCheckResponse( 332dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUnresponsiveTime + TimeDelta::FromMinutes(1), SUCCESSFUL); 333dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(io_watcher_->success_response_, static_cast<uint64>(0)); 334dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(io_watcher_->failed_response_, static_cast<uint64>(0)); 335dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // DeActivate thread watching for shutdown. 337dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 338dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 339dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod(io_watcher_, &ThreadWatcher::DeActivateThreadWatching)); 340dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 341dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// This test posts a task on watched thread that takes very long time (this is 343dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// to simulate hanging of watched thread). It then checks for 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// OnCheckResponsiveness raising an alert (OnCheckResponsiveness returns false 345dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// if the watched thread is not responding). 346dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(ThreadWatcherTest, ThreadNotResponding) { 347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Simulate hanging of watched thread by making the watched thread wait for a 348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // very long time by posting a task on watched thread that keeps it busy. 349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BrowserThread::PostTask( 350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_thread_id, 351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod( 353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_, 354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen &CustomThreadWatcher::VeryLongMethod, 355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUnresponsiveTime * 10)); 356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Activate thread watching. 358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 359dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 360dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod(io_watcher_, &ThreadWatcher::ActivateThreadWatching)); 361dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Verify watched thread is not responding for ping messages. 363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_->WaitForCheckResponse( 364dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUnresponsiveTime + TimeDelta::FromMinutes(1), FAILED); 365dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(io_watcher_->success_response_, static_cast<uint64>(0)); 366dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(io_watcher_->failed_response_, static_cast<uint64>(0)); 367dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 368dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // DeActivate thread watching for shutdown. 369dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 370dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 371dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod(io_watcher_, &ThreadWatcher::DeActivateThreadWatching)); 372dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 373dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Wait for the io_watcher_'s VeryLongMethod to finish. 374dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_->WaitForWaitStateChange(kUnresponsiveTime * 10, ALL_DONE); 375dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 376dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 377dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Test watching of multiple threads with all threads not responding. 378dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(ThreadWatcherTest, MultipleThreadsResponding) { 379dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check for WEBKIT thread to perform ping/pong messaging. 380dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 381dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 382dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod( 383dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_watcher_, &ThreadWatcher::ActivateThreadWatching)); 384dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 385dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check for IO thread to perform ping/pong messaging. 386dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 387dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 388dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod(io_watcher_, &ThreadWatcher::ActivateThreadWatching)); 389dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 390dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Verify WEBKIT thread is responding with ping/pong messaging. 391dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_watcher_->WaitForCheckResponse( 392dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUnresponsiveTime + TimeDelta::FromMinutes(1), SUCCESSFUL); 393dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(webkit_watcher_->ping_sent_, static_cast<uint64>(0)); 394dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(webkit_watcher_->pong_received_, static_cast<uint64>(0)); 395dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GE(webkit_watcher_->ping_sequence_number_, static_cast<uint64>(0)); 396dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(webkit_watcher_->success_response_, static_cast<uint64>(0)); 397dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(webkit_watcher_->failed_response_, static_cast<uint64>(0)); 398dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 399dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Verify IO thread is responding with ping/pong messaging. 400dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_->WaitForCheckResponse( 401dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUnresponsiveTime + TimeDelta::FromMinutes(1), SUCCESSFUL); 402dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(io_watcher_->ping_sent_, static_cast<uint64>(0)); 403dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(io_watcher_->pong_received_, static_cast<uint64>(0)); 404dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GE(io_watcher_->ping_sequence_number_, static_cast<uint64>(0)); 405dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(io_watcher_->success_response_, static_cast<uint64>(0)); 406dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(io_watcher_->failed_response_, static_cast<uint64>(0)); 407dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 408dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // DeActivate thread watching for shutdown. 409dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 410dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 411dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod(io_watcher_, &ThreadWatcher::DeActivateThreadWatching)); 412dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 413dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 414dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 415dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod( 416dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_watcher_, &ThreadWatcher::DeActivateThreadWatching)); 417dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 418dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 419dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Test watching of multiple threads with one of the threads not responding. 420dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(ThreadWatcherTest, MultipleThreadsNotResponding) { 421dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Simulate hanging of watched thread by making the watched thread wait for a 422dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // very long time by posting a task on watched thread that keeps it busy. 423dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BrowserThread::PostTask( 424dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_thread_id, 425dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 426dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod( 427dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_, 428dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen &CustomThreadWatcher::VeryLongMethod, 429dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUnresponsiveTime * 10)); 430dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 431dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Activate watching of WEBKIT thread. 432dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 433dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 434dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod( 435dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_watcher_, &ThreadWatcher::ActivateThreadWatching)); 436dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 437dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Activate watching of IO thread. 438dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 439dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 440dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod(io_watcher_, &ThreadWatcher::ActivateThreadWatching)); 441dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 442dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Verify WEBKIT thread is responding with ping/pong messaging. 443dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_watcher_->WaitForCheckResponse( 444dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUnresponsiveTime + TimeDelta::FromMinutes(1), SUCCESSFUL); 445dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(webkit_watcher_->success_response_, static_cast<uint64>(0)); 446dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(webkit_watcher_->failed_response_, static_cast<uint64>(0)); 447dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 448dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Verify IO thread is not responding for ping messages. 449dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_->WaitForCheckResponse( 450dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kUnresponsiveTime + TimeDelta::FromMinutes(1), FAILED); 451dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(io_watcher_->success_response_, static_cast<uint64>(0)); 452dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_GT(io_watcher_->failed_response_, static_cast<uint64>(0)); 453dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 454dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // DeActivate thread watching for shutdown. 455dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 456dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 457dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod(io_watcher_, &ThreadWatcher::DeActivateThreadWatching)); 458dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WatchDogThread::PostTask( 459dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FROM_HERE, 460dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewRunnableMethod( 461dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen webkit_watcher_, &ThreadWatcher::DeActivateThreadWatching)); 462dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 463dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Wait for the io_watcher_'s VeryLongMethod to finish. 464dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen io_watcher_->WaitForWaitStateChange(kUnresponsiveTime * 10, ALL_DONE); 465dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 466