• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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