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 "content/public/common/web_preferences.h" 20 #include "content/shell/common/leak_detection_result.h" 21 #include "ui/gfx/size.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 reset()49 void reset() { 50 state_ = DURING_TEST; 51 } output_finished()52 bool output_finished() const { return state_ == AFTER_TEST; } set_capture_text_only(bool capture_text_only)53 void set_capture_text_only(bool capture_text_only) { 54 capture_text_only_ = capture_text_only; 55 } 56 set_encode_binary_data(bool encode_binary_data)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 void CloseStderr(); 79 80 private: 81 void PrintEncodedBinaryData(const std::vector<unsigned char>& data); 82 83 enum State { 84 DURING_TEST, 85 IN_TEXT_BLOCK, 86 IN_AUDIO_BLOCK, 87 IN_IMAGE_BLOCK, 88 AFTER_TEST 89 }; 90 State state_; 91 92 bool capture_text_only_; 93 bool encode_binary_data_; 94 95 std::ostream* output_; 96 std::ostream* error_; 97 98 DISALLOW_COPY_AND_ASSIGN(WebKitTestResultPrinter); 99 }; 100 101 class WebKitTestController : public base::NonThreadSafe, 102 public WebContentsObserver, 103 public NotificationObserver, 104 public GpuDataManagerObserver { 105 public: 106 static WebKitTestController* Get(); 107 108 WebKitTestController(); 109 virtual ~WebKitTestController(); 110 111 // True if the controller is ready for testing. 112 bool PrepareForLayoutTest(const GURL& test_url, 113 const base::FilePath& current_working_directory, 114 bool enable_pixel_dumping, 115 const std::string& expected_pixel_hash); 116 // True if the controller was reset successfully. 117 bool ResetAfterLayoutTest(); 118 119 void SetTempPath(const base::FilePath& temp_path); 120 void RendererUnresponsive(); 121 void WorkerCrashed(); 122 void OverrideWebkitPrefs(WebPreferences* prefs); 123 void OpenURL(const GURL& url); 124 void TestFinishedInSecondaryWindow(); 125 bool IsMainWindow(WebContents* web_contents) const; 126 printer()127 WebKitTestResultPrinter* printer() { return printer_.get(); } set_printer(WebKitTestResultPrinter * printer)128 void set_printer(WebKitTestResultPrinter* printer) { 129 printer_.reset(printer); 130 } 131 132 void DevToolsProcessCrashed(); 133 134 // WebContentsObserver implementation. 135 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 136 virtual void PluginCrashed(const base::FilePath& plugin_path, 137 base::ProcessId plugin_pid) OVERRIDE; 138 virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; 139 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE; 140 virtual void WebContentsDestroyed() OVERRIDE; 141 142 // NotificationObserver implementation. 143 virtual void Observe(int type, 144 const NotificationSource& source, 145 const NotificationDetails& details) OVERRIDE; 146 147 // GpuDataManagerObserver implementation. 148 virtual void OnGpuProcessCrashed(base::TerminationStatus exit_code) OVERRIDE; 149 150 private: 151 enum TestPhase { 152 BETWEEN_TESTS, 153 DURING_TEST, 154 CLEAN_UP 155 }; 156 157 static WebKitTestController* instance_; 158 159 void DiscardMainWindow(); 160 void SendTestConfiguration(); 161 162 // Message handlers. 163 void OnAudioDump(const std::vector<unsigned char>& audio_dump); 164 void OnImageDump(const std::string& actual_pixel_hash, const SkBitmap& image); 165 void OnTextDump(const std::string& dump); 166 void OnPrintMessage(const std::string& message); 167 void OnOverridePreferences(const WebPreferences& prefs); 168 void OnTestFinished(); 169 void OnClearDevToolsLocalStorage(); 170 void OnShowDevTools(const std::string& settings, 171 const std::string& frontend_url); 172 void OnCloseDevTools(); 173 void OnGoToOffset(int offset); 174 void OnReload(); 175 void OnLoadURLForFrame(const GURL& url, const std::string& frame_name); 176 void OnCaptureSessionHistory(); 177 void OnCloseRemainingWindows(); 178 void OnResetDone(); 179 void OnLeakDetectionDone(const content::LeakDetectionResult& result); 180 181 scoped_ptr<WebKitTestResultPrinter> printer_; 182 183 base::FilePath current_working_directory_; 184 base::FilePath temp_path_; 185 186 Shell* main_window_; 187 188 // The PID of the render process of the render view host of main_window_. 189 int current_pid_; 190 191 // True if we should set the test configuration to the next RenderViewHost 192 // created. 193 bool send_configuration_to_next_host_; 194 195 // What phase of running an individual test we are currently in. 196 TestPhase test_phase_; 197 198 // True if the currently running test is a compositing test. 199 bool is_compositing_test_; 200 201 // Per test config. 202 bool enable_pixel_dumping_; 203 std::string expected_pixel_hash_; 204 gfx::Size initial_size_; 205 GURL test_url_; 206 207 // True if the WebPreferences of newly created RenderViewHost should be 208 // overridden with prefs_. 209 bool should_override_prefs_; 210 WebPreferences prefs_; 211 212 NotificationRegistrar registrar_; 213 214 const bool is_leak_detection_enabled_; 215 bool crash_when_leak_found_; 216 217 #if defined(OS_ANDROID) 218 // Because of the nested message pump implementation, Android needs to allow 219 // waiting on the UI thread while layout tests are being ran. 220 ScopedAllowWaitForAndroidLayoutTests reduced_restrictions_; 221 #endif 222 223 DISALLOW_COPY_AND_ASSIGN(WebKitTestController); 224 }; 225 226 } // namespace content 227 228 #endif // CONTENT_SHELL_BROWSER_WEBKIT_TEST_CONTROLLER_H_ 229