Home | History | Annotate | Download | only in browser
      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 
     48   void reset() {
     49     state_ = DURING_TEST;
     50   }
     51   bool output_finished() const { return state_ == AFTER_TEST; }
     52   void set_capture_text_only(bool capture_text_only) {
     53     capture_text_only_ = capture_text_only;
     54   }
     55 
     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 
    126   WebKitTestResultPrinter* printer() { return printer_.get(); }
    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