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_SHELL_WEBKIT_TEST_CONTROLLER_H_ 6 #define CONTENT_SHELL_WEBKIT_TEST_CONTROLLER_H_ 7 8 #include <ostream> 9 #include <string> 10 11 #include "base/cancelable_callback.h" 12 #include "base/files/file_path.h" 13 #include "base/synchronization/lock.h" 14 #include "base/threading/non_thread_safe.h" 15 #include "content/public/browser/gpu_data_manager_observer.h" 16 #include "content/public/browser/notification_observer.h" 17 #include "content/public/browser/notification_registrar.h" 18 #include "content/public/browser/render_view_host_observer.h" 19 #include "content/public/browser/web_contents_observer.h" 20 #include "ui/gfx/size.h" 21 #include "webkit/common/webpreferences.h" 22 23 #if defined(OS_ANDROID) 24 #include "base/threading/thread_restrictions.h" 25 #endif 26 27 class SkBitmap; 28 29 namespace content { 30 31 class Shell; 32 33 #if defined(OS_ANDROID) 34 // Android uses a nested message loop for running layout tests because the 35 // default message loop, provided by the system, does not offer a blocking 36 // Run() method. The loop itself, implemented as NestedMessagePumpAndroid, 37 // uses a base::WaitableEvent allowing it to sleep until more events arrive. 38 class ScopedAllowWaitForAndroidLayoutTests { 39 private: 40 base::ThreadRestrictions::ScopedAllowWait wait; 41 }; 42 #endif 43 44 class WebKitTestResultPrinter { 45 public: 46 WebKitTestResultPrinter(std::ostream* output, std::ostream* error); 47 ~WebKitTestResultPrinter(); 48 49 void reset() { 50 state_ = DURING_TEST; 51 } 52 bool output_finished() const { return state_ == AFTER_TEST; } 53 void set_capture_text_only(bool capture_text_only) { 54 capture_text_only_ = capture_text_only; 55 } 56 57 void set_encode_binary_data(bool encode_binary_data) { 58 encode_binary_data_ = encode_binary_data; 59 } 60 61 void PrintTextHeader(); 62 void PrintTextBlock(const std::string& block); 63 void PrintTextFooter(); 64 65 void PrintImageHeader(const std::string& actual_hash, 66 const std::string& expected_hash); 67 void PrintImageBlock(const std::vector<unsigned char>& png_image); 68 void PrintImageFooter(); 69 70 void PrintAudioHeader(); 71 void PrintAudioBlock(const std::vector<unsigned char>& audio_data); 72 void PrintAudioFooter(); 73 74 void AddMessage(const std::string& message); 75 void AddMessageRaw(const std::string& message); 76 void AddErrorMessage(const std::string& message); 77 78 private: 79 void PrintEncodedBinaryData(const std::vector<unsigned char>& data); 80 81 enum State { 82 DURING_TEST, 83 IN_TEXT_BLOCK, 84 IN_AUDIO_BLOCK, 85 IN_IMAGE_BLOCK, 86 AFTER_TEST 87 }; 88 State state_; 89 90 bool capture_text_only_; 91 bool encode_binary_data_; 92 93 std::ostream* output_; 94 std::ostream* error_; 95 96 DISALLOW_COPY_AND_ASSIGN(WebKitTestResultPrinter); 97 }; 98 99 class WebKitTestController : public base::NonThreadSafe, 100 public WebContentsObserver, 101 public NotificationObserver, 102 public GpuDataManagerObserver { 103 public: 104 static WebKitTestController* Get(); 105 106 WebKitTestController(); 107 virtual ~WebKitTestController(); 108 109 // True if the controller is ready for testing. 110 bool PrepareForLayoutTest(const GURL& test_url, 111 const base::FilePath& current_working_directory, 112 bool enable_pixel_dumping, 113 const std::string& expected_pixel_hash); 114 // True if the controller was reset successfully. 115 bool ResetAfterLayoutTest(); 116 117 void SetTempPath(const base::FilePath& temp_path); 118 void RendererUnresponsive(); 119 void WorkerCrashed(); 120 void OverrideWebkitPrefs(WebPreferences* prefs); 121 void OpenURL(const GURL& url); 122 void TestFinishedInSecondaryWindow(); 123 bool IsMainWindow(WebContents* web_contents) const; 124 125 WebKitTestResultPrinter* printer() { return printer_.get(); } 126 void set_printer(WebKitTestResultPrinter* printer) { 127 printer_.reset(printer); 128 } 129 130 // WebContentsObserver implementation. 131 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 132 virtual void PluginCrashed(const base::FilePath& plugin_path, 133 base::ProcessId plugin_pid) OVERRIDE; 134 virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; 135 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE; 136 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE; 137 138 // NotificationObserver implementation. 139 virtual void Observe(int type, 140 const NotificationSource& source, 141 const NotificationDetails& details) OVERRIDE; 142 143 // GpuDataManagerObserver implementation. 144 virtual void OnGpuProcessCrashed(base::TerminationStatus exit_code) OVERRIDE; 145 146 private: 147 enum TestPhase { 148 BETWEEN_TESTS, 149 DURING_TEST, 150 CLEAN_UP 151 }; 152 153 static WebKitTestController* instance_; 154 155 void TimeoutHandler(); 156 void DiscardMainWindow(); 157 void SendTestConfiguration(); 158 159 // Message handlers. 160 void OnAudioDump(const std::vector<unsigned char>& audio_dump); 161 void OnImageDump(const std::string& actual_pixel_hash, const SkBitmap& image); 162 void OnTextDump(const std::string& dump); 163 void OnPrintMessage(const std::string& message); 164 void OnOverridePreferences(const WebPreferences& prefs); 165 void OnTestFinished(); 166 void OnShowDevTools(); 167 void OnCloseDevTools(); 168 void OnGoToOffset(int offset); 169 void OnReload(); 170 void OnLoadURLForFrame(const GURL& url, const std::string& frame_name); 171 void OnCaptureSessionHistory(); 172 void OnCloseRemainingWindows(); 173 void OnResetDone(); 174 175 scoped_ptr<WebKitTestResultPrinter> printer_; 176 177 base::FilePath current_working_directory_; 178 base::FilePath temp_path_; 179 180 Shell* main_window_; 181 182 // The PID of the render process of the render view host of main_window_. 183 int current_pid_; 184 185 // True if we should set the test configuration to the next RenderViewHost 186 // created. 187 bool send_configuration_to_next_host_; 188 189 // What phase of running an individual test we are currently in. 190 TestPhase test_phase_; 191 192 // True if the currently running test is a compositing test. 193 bool is_compositing_test_; 194 195 // Per test config. 196 bool enable_pixel_dumping_; 197 std::string expected_pixel_hash_; 198 gfx::Size initial_size_; 199 GURL test_url_; 200 201 // True if the WebPreferences of newly created RenderViewHost should be 202 // overridden with prefs_. 203 bool should_override_prefs_; 204 WebPreferences prefs_; 205 206 NotificationRegistrar registrar_; 207 208 #if defined(OS_ANDROID) 209 // Because of the nested message pump implementation, Android needs to allow 210 // waiting on the UI thread while layout tests are being ran. 211 ScopedAllowWaitForAndroidLayoutTests reduced_restrictions_; 212 #endif 213 214 DISALLOW_COPY_AND_ASSIGN(WebKitTestController); 215 }; 216 217 } // namespace content 218 219 #endif // CONTENT_SHELL_WEBKIT_TEST_CONTROLLER_H_ 220