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