• 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 "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