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