Home | History | Annotate | Download | only in support
      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 #include "webkit/support/webkit_support.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/debug/debugger.h"
      9 #include "base/debug/stack_trace.h"
     10 #include "base/logging.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/path_service.h"
     13 #include "base/process/memory.h"
     14 #include "base/run_loop.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "third_party/WebKit/public/web/WebCache.h"
     17 #include "third_party/WebKit/public/web/WebKit.h"
     18 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
     19 #include "url/url_util.h"
     20 #include "webkit/child/webkitplatformsupport_impl.h"
     21 #include "webkit/common/user_agent/user_agent.h"
     22 #include "webkit/common/user_agent/user_agent_util.h"
     23 #include "webkit/glue/webkit_glue.h"
     24 #include "webkit/support/platform_support.h"
     25 #include "webkit/support/test_webkit_platform_support.h"
     26 
     27 #if defined(OS_ANDROID)
     28 #include "base/test/test_support_android.h"
     29 #endif
     30 
     31 namespace {
     32 
     33 // All fatal log messages (e.g. DCHECK failures) imply unit test failures
     34 void UnitTestAssertHandler(const std::string& str) {
     35   FAIL() << str;
     36 }
     37 
     38 void InitLogging() {
     39 #if defined(OS_WIN)
     40   if (!::IsDebuggerPresent()) {
     41     UINT new_flags = SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX
     42         | SEM_NOGPFAULTERRORBOX;
     43 
     44     // Preserve existing error mode, as discussed at
     45     // http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx
     46     UINT existing_flags = SetErrorMode(new_flags);
     47     SetErrorMode(existing_flags | new_flags);
     48 
     49     // Don't pop up dialog on assertion failure, log to stdout instead.
     50     _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
     51     _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
     52   }
     53 #endif
     54 
     55 #if defined(OS_ANDROID)
     56   // On Android we expect the log to appear in logcat.
     57   base::InitAndroidTestLogging();
     58 #else
     59   base::FilePath log_filename;
     60   PathService::Get(base::DIR_EXE, &log_filename);
     61   log_filename = log_filename.AppendASCII("DumpRenderTree.log");
     62   logging::LoggingSettings settings;
     63   // Only log to a file. This prevents debugging output from disrupting
     64   // whether or not we pass.
     65   settings.logging_dest = logging::LOG_TO_FILE;
     66   settings.log_file = log_filename.value().c_str();
     67   settings.delete_old = logging::DELETE_OLD_LOG_FILE;
     68   logging::InitLogging(settings);
     69 
     70   // We want process and thread IDs because we may have multiple processes.
     71   const bool kProcessId = true;
     72   const bool kThreadId = true;
     73   const bool kTimestamp = true;
     74   const bool kTickcount = true;
     75   logging::SetLogItems(kProcessId, kThreadId, !kTimestamp, kTickcount);
     76 #endif  // else defined(OS_ANDROID)
     77 }
     78 
     79 class TestEnvironment {
     80  public:
     81 #if defined(OS_ANDROID)
     82   // Android UI message loop goes through Java, so don't use it in tests.
     83   typedef base::MessageLoop MessageLoopType;
     84 #else
     85   typedef base::MessageLoopForUI MessageLoopType;
     86 #endif
     87 
     88   TestEnvironment() {
     89     logging::SetLogAssertHandler(UnitTestAssertHandler);
     90     main_message_loop_.reset(new MessageLoopType);
     91 
     92     // TestWebKitPlatformSupport must be instantiated after MessageLoopType.
     93     webkit_platform_support_.reset(new TestWebKitPlatformSupport);
     94   }
     95 
     96   TestWebKitPlatformSupport* webkit_platform_support() const {
     97     return webkit_platform_support_.get();
     98   }
     99 
    100  private:
    101   scoped_ptr<MessageLoopType> main_message_loop_;
    102   scoped_ptr<TestWebKitPlatformSupport> webkit_platform_support_;
    103 };
    104 
    105 TestEnvironment* test_environment;
    106 
    107 }  // namespace
    108 
    109 namespace webkit_support {
    110 
    111 void SetUpTestEnvironmentForUnitTests() {
    112   base::debug::EnableInProcessStackDumping();
    113   base::EnableTerminationOnHeapCorruption();
    114 
    115   // Initialize the singleton CommandLine with fixed values.  Some code refer to
    116   // CommandLine::ForCurrentProcess().  We don't use the actual command-line
    117   // arguments of DRT to avoid unexpected behavior change.
    118   //
    119   // webkit/glue/plugin/plugin_list_posix.cc checks --debug-plugin-loading.
    120   // webkit/glue/plugin/plugin_list_win.cc checks --old-wmp.
    121   // If DRT needs these flags, specify them in the following kFixedArguments.
    122   const char* kFixedArguments[] = {"DumpRenderTree"};
    123   CommandLine::Init(arraysize(kFixedArguments), kFixedArguments);
    124 
    125   WebKit::WebRuntimeFeatures::enableStableFeatures(true);
    126   WebKit::WebRuntimeFeatures::enableExperimentalFeatures(true);
    127   WebKit::WebRuntimeFeatures::enableTestOnlyFeatures(true);
    128 
    129   // Explicitly initialize the GURL library before spawning any threads.
    130   // Otherwise crash may happend when different threads try to create a GURL
    131   // at same time.
    132   url_util::Initialize();
    133   webkit_support::BeforeInitialize();
    134   test_environment = new TestEnvironment;
    135   webkit_support::AfterInitialize();
    136   webkit_glue::SetUserAgent(webkit_glue::BuildUserAgentFromProduct(
    137       "DumpRenderTree/0.0.0.0"), false);
    138 }
    139 
    140 void TearDownTestEnvironment() {
    141   // Flush any remaining messages before we kill ourselves.
    142   // http://code.google.com/p/chromium/issues/detail?id=9500
    143   base::RunLoop().RunUntilIdle();
    144 
    145   BeforeShutdown();
    146   if (RunningOnValgrind())
    147     WebKit::WebCache::clear();
    148   WebKit::shutdown();
    149   delete test_environment;
    150   test_environment = NULL;
    151   AfterShutdown();
    152   logging::CloseLogFile();
    153 }
    154 
    155 }  // namespace webkit_support
    156