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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_PUBLIC_TEST_TEST_UTILS_H_ 6 #define CONTENT_PUBLIC_TEST_TEST_UTILS_H_ 7 8 #include "base/callback.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/run_loop.h" 12 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/notification_details.h" 14 #include "content/public/browser/notification_observer.h" 15 #include "content/public/browser/notification_registrar.h" 16 #include "content/public/browser/notification_source.h" 17 18 namespace base { 19 class Value; 20 } 21 22 // A collection of functions designed for use with unit and browser tests. 23 24 namespace content { 25 26 class RenderViewHost; 27 28 // Turns on nestable tasks, runs the message loop, then resets nestable tasks 29 // to what they were originally. Prefer this over MessageLoop::Run for in 30 // process browser tests that need to block until a condition is met. 31 void RunMessageLoop(); 32 33 // Variant of RunMessageLoop that takes RunLoop. 34 void RunThisRunLoop(base::RunLoop* run_loop); 35 36 // Turns on nestable tasks, runs all pending tasks in the message loop, 37 // then resets nestable tasks to what they were originally. Prefer this 38 // over MessageLoop::RunAllPending for in process browser tests to run 39 // all pending tasks. 40 void RunAllPendingInMessageLoop(); 41 42 // Blocks the current thread until all the pending messages in the loop of the 43 // thread |thread_id| have been processed. 44 void RunAllPendingInMessageLoop(BrowserThread::ID thread_id); 45 46 // Get task to quit the given RunLoop. It allows a few generations of pending 47 // tasks to run as opposed to run_loop->QuitClosure(). 48 base::Closure GetQuitTaskForRunLoop(base::RunLoop* run_loop); 49 50 // Executes the specified javascript in the top-level frame, and runs a nested 51 // MessageLoop. When the result is available, it is returned. 52 // This should not be used; the use of the ExecuteScript functions in 53 // browser_test_utils is preferable. 54 scoped_ptr<base::Value> ExecuteScriptAndGetValue( 55 RenderViewHost* render_view_host, 56 const std::string& script); 57 58 // Helper class to Run and Quit the message loop. Run and Quit can only happen 59 // once per instance. Make a new instance for each use. Calling Quit after Run 60 // has returned is safe and has no effect. 61 class MessageLoopRunner : public base::RefCounted<MessageLoopRunner> { 62 public: 63 MessageLoopRunner(); 64 65 // Run the current MessageLoop unless the quit closure 66 // has already been called. 67 void Run(); 68 69 // Quit the matching call to Run (nested MessageLoops are unaffected). 70 void Quit(); 71 72 // Hand this closure off to code that uses callbacks to notify completion. 73 // Example: 74 // scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 75 // kick_off_some_api(runner->QuitClosure()); 76 // runner->Run(); 77 base::Closure QuitClosure(); 78 79 private: 80 friend class base::RefCounted<MessageLoopRunner>; 81 ~MessageLoopRunner(); 82 83 // True when the message loop is running. 84 bool loop_running_; 85 86 // True after closure returned by |QuitClosure| has been called. 87 bool quit_closure_called_; 88 89 base::RunLoop run_loop_; 90 91 DISALLOW_COPY_AND_ASSIGN(MessageLoopRunner); 92 }; 93 94 // A WindowedNotificationObserver allows code to wait until a condition is met. 95 // Simple conditions are specified by providing a |notification_type| and a 96 // |source|. When a notification of the expected type from the expected source 97 // is received, the condition is met. 98 // More complex conditions can be specified by providing a |notification_type| 99 // and a |callback|. The callback is called whenever the notification is fired. 100 // If the callback returns |true|, the condition is met. Otherwise, the 101 // condition is not yet met and the callback will be invoked again every time a 102 // notification of the expected type is received until the callback returns 103 // |true|. 104 // 105 // This helper class exists to avoid the following common pattern in tests: 106 // PerformAction() 107 // WaitForCompletionNotification() 108 // The pattern leads to flakiness as there is a window between PerformAction 109 // returning and the observers getting registered, where a notification will be 110 // missed. 111 // 112 // Rather, one can do this: 113 // WindowedNotificationObserver signal(...) 114 // PerformAction() 115 // signal.Wait() 116 class WindowedNotificationObserver : public NotificationObserver { 117 public: 118 // Callback invoked on notifications. Should return |true| when the condition 119 // being waited for is met. 120 typedef base::Callback<bool(void)> ConditionTestCallback; 121 122 // Set up to wait for a simple condition. The condition is met when a 123 // notification of the given |notification_type| from the given |source| is 124 // received. To accept notifications from all sources, specify 125 // NotificationService::AllSources() as |source|. 126 WindowedNotificationObserver(int notification_type, 127 const NotificationSource& source); 128 129 // Set up to wait for a complex condition. The condition is met when 130 // |callback| returns |true|. The callback is invoked whenever a notification 131 // of |notification_type| from any source is received. 132 WindowedNotificationObserver(int notification_type, 133 const ConditionTestCallback& callback); 134 135 virtual ~WindowedNotificationObserver(); 136 137 // Wait until the specified condition is met. If the condition is already met 138 // (that is, the expected notification has already been received or the 139 // given callback returns |true| already), Wait() returns immediately. 140 void Wait(); 141 142 // Returns NotificationService::AllSources() if we haven't observed a 143 // notification yet. 144 const NotificationSource& source() const { 145 return source_; 146 } 147 148 const NotificationDetails& details() const { 149 return details_; 150 } 151 152 // NotificationObserver: 153 virtual void Observe(int type, 154 const NotificationSource& source, 155 const NotificationDetails& details) OVERRIDE; 156 157 private: 158 bool seen_; 159 bool running_; 160 NotificationRegistrar registrar_; 161 162 ConditionTestCallback callback_; 163 164 NotificationSource source_; 165 NotificationDetails details_; 166 scoped_refptr<MessageLoopRunner> message_loop_runner_; 167 168 DISALLOW_COPY_AND_ASSIGN(WindowedNotificationObserver); 169 }; 170 171 } // namespace content 172 173 #endif // CONTENT_PUBLIC_TEST_TEST_UTILS_H_ 174