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 "content/shell/common/leak_detection_result.h"
     20 #include "ui/gfx/size.h"
     21 #include "webkit/common/webpreferences.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 
     49   void reset() {
     50     state_ = DURING_TEST;
     51   }
     52   bool output_finished() const { return state_ == AFTER_TEST; }
     53   void set_capture_text_only(bool capture_text_only) {
     54     capture_text_only_ = capture_text_only;
     55   }
     56 
     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 
    127   WebKitTestResultPrinter* printer() { return printer_.get(); }
    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 
    216 #if defined(OS_ANDROID)
    217   // Because of the nested message pump implementation, Android needs to allow
    218   // waiting on the UI thread while layout tests are being ran.
    219   ScopedAllowWaitForAndroidLayoutTests reduced_restrictions_;
    220 #endif
    221 
    222   DISALLOW_COPY_AND_ASSIGN(WebKitTestController);
    223 };
    224 
    225 }  // namespace content
    226 
    227 #endif  // CONTENT_SHELL_BROWSER_WEBKIT_TEST_CONTROLLER_H_
    228