cef/tests/ceftests/test_suite.cc

222 lines
7.1 KiB
C++
Raw Permalink Normal View History

// Copyright 2016 The Chromium Embedded Framework Authors. Postions copyright
// 2012 The Chromium Authors. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.
#include "tests/ceftests/test_suite.h"
Introduce the use of Chromium types (issue #1336). Changes to the CEF public API: - Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types. - Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask. - Change CefRefPtr to extend scoped_refptr. -- Change CefBase method signatures to match RefCountedThreadSafeBase. - Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*. -- Remove the CefAtomic* functions. -- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro. - Change IMPLEMENT_LOCKING to use base::Lock. -- Remove the CefCriticalSection class. -- Deprecate the IMPLEMENT_LOCKING macro. -- base::Lock will DCHECK() in Debug builds if lock usage is reentrant. - Move include/internal/cef_tuple.h to include/base/cef_tuple.h. - Allow an empty |callback| parameter passed to CefBeginTracing. Changes to the CEF implementation: - Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro. - Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cef_unittests: - Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types. - Fix wrong header include ordering. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cefclient and cefsimple: - Use base::Bind and cef_closure_task.h instead of NewCefRunnable*. - Remove use of the IMPEMENT_LOCKING macro. - Fix incorrect/unnecessary locking. - Add additional runtime thread checks. - Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2014-07-15 00:18:51 +02:00
#include "include/base/cef_logging.h"
#include "include/cef_file_util.h"
#include "include/test/cef_test_helpers.h"
#include "include/wrapper/cef_scoped_temp_dir.h"
#include "tests/gtest/include/gtest/gtest.h"
#include "tests/gtest/teamcity/include/teamcity_gtest.h"
#include "tests/shared/browser/resource_util.h"
#include "tests/shared/common/client_switches.h"
namespace {
Introduce the use of Chromium types (issue #1336). Changes to the CEF public API: - Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types. - Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask. - Change CefRefPtr to extend scoped_refptr. -- Change CefBase method signatures to match RefCountedThreadSafeBase. - Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*. -- Remove the CefAtomic* functions. -- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro. - Change IMPLEMENT_LOCKING to use base::Lock. -- Remove the CefCriticalSection class. -- Deprecate the IMPLEMENT_LOCKING macro. -- base::Lock will DCHECK() in Debug builds if lock usage is reentrant. - Move include/internal/cef_tuple.h to include/base/cef_tuple.h. - Allow an empty |callback| parameter passed to CefBeginTracing. Changes to the CEF implementation: - Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro. - Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cef_unittests: - Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types. - Fix wrong header include ordering. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cefclient and cefsimple: - Use base::Bind and cef_closure_task.h instead of NewCefRunnable*. - Remove use of the IMPEMENT_LOCKING macro. - Fix incorrect/unnecessary locking. - Add additional runtime thread checks. - Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2014-07-15 00:18:51 +02:00
CefTestSuite* g_test_suite = nullptr;
#if defined(OS_WIN)
// From base/process/launch_win.cc.
void RouteStdioToConsole(bool create_console_if_not_found) {
// Don't change anything if stdout or stderr already point to a
// valid stream.
//
// If we are running under Buildbot or under Cygwin's default
// terminal (mintty), stderr and stderr will be pipe handles. In
// that case, we don't want to open CONOUT$, because its output
// likely does not go anywhere.
//
// We don't use GetStdHandle() to check stdout/stderr here because
// it can return dangling IDs of handles that were never inherited
// by this process. These IDs could have been reused by the time
// this function is called. The CRT checks the validity of
// stdout/stderr on startup (before the handle IDs can be reused).
// _fileno(stdout) will return -2 (_NO_CONSOLE_FILENO) if stdout was
// invalid.
if (_fileno(stdout) >= 0 || _fileno(stderr) >= 0) {
return;
}
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
unsigned int result = GetLastError();
// Was probably already attached.
2023-01-02 23:59:03 +01:00
if (result == ERROR_ACCESS_DENIED) {
return;
2023-01-02 23:59:03 +01:00
}
// Don't bother creating a new console for each child process if the
// parent process is invalid (eg: crashed).
2023-01-02 23:59:03 +01:00
if (result == ERROR_GEN_FAILURE) {
return;
2023-01-02 23:59:03 +01:00
}
if (create_console_if_not_found) {
// Make a new console if attaching to parent fails with any other error.
// It should be ERROR_INVALID_HANDLE at this point, which means the
// browser was likely not started from a console.
AllocConsole();
} else {
return;
}
}
// Arbitrary byte count to use when buffering output lines. More
// means potential waste, less means more risk of interleaved
// log-lines in output.
enum { kOutputBufferSize = 64 * 1024 };
if (freopen("CONOUT$", "w", stdout)) {
setvbuf(stdout, nullptr, _IOLBF, kOutputBufferSize);
// Overwrite FD 1 for the benefit of any code that uses this FD
// directly. This is safe because the CRT allocates FDs 0, 1 and
// 2 at startup even if they don't have valid underlying Windows
// handles. This means we won't be overwriting an FD created by
// _open() after startup.
_dup2(_fileno(stdout), 1);
}
if (freopen("CONOUT$", "w", stderr)) {
setvbuf(stderr, nullptr, _IOLBF, kOutputBufferSize);
_dup2(_fileno(stderr), 2);
}
// Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog.
std::ios::sync_with_stdio();
}
#endif // defined(OS_WIN)
} // namespace
CefTestSuite::CefTestSuite(int argc, char** argv)
: argc_(argc), argv_(argc, argv) {
g_test_suite = this;
// Keep a representation of the original command-line.
command_line_ = CefCommandLine::CreateCommandLine();
#if defined(OS_WIN)
command_line_->InitFromString(::GetCommandLineW());
#else
command_line_->InitFromArgv(argc, argv);
#endif
if (!command_line_->HasSwitch("type")) {
// Initialize in the main process only.
root_cache_path_ =
command_line_->GetSwitchValue(client::switches::kCachePath);
if (root_cache_path_.empty()) {
CefScopedTempDir temp_dir;
CHECK(temp_dir.CreateUniqueTempDir());
root_cache_path_ = temp_dir.Take();
RegisterTempDirectory(root_cache_path_);
}
}
}
CefTestSuite::~CefTestSuite() {
g_test_suite = nullptr;
}
// static
CefTestSuite* CefTestSuite::GetInstance() {
return g_test_suite;
}
void CefTestSuite::InitMainProcess() {
PreInitialize();
// This will modify |argc_| and |argv_|.
testing::InitGoogleTest(&argc_, argv_.array());
if (jetbrains::teamcity::underTeamcity()) {
auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
listeners.Append(
new jetbrains::teamcity::TeamcityGoogleTestEventListener());
}
}
// Don't add additional code to this method. Instead add it to Initialize().
int CefTestSuite::Run() {
Initialize();
retval_ = RUN_ALL_TESTS();
Shutdown();
return retval_;
}
void CefTestSuite::GetSettings(CefSettings& settings) const {
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
// Enable the experimental Chrome runtime. See issue #2969 for details.
settings.chrome_runtime =
command_line_->HasSwitch(client::switches::kEnableChromeRuntime);
CefString(&settings.cache_path) = root_cache_path_;
CefString(&settings.root_cache_path) = root_cache_path_;
// Always expose the V8 gc() function to give tests finer-grained control over
// memory management.
std::string javascript_flags = "--expose-gc";
// Value of kJavascriptFlags switch.
std::string other_javascript_flags =
command_line_->GetSwitchValue("js-flags");
2023-01-02 23:59:03 +01:00
if (!other_javascript_flags.empty()) {
javascript_flags += " " + other_javascript_flags;
2023-01-02 23:59:03 +01:00
}
CefString(&settings.javascript_flags) = javascript_flags;
// Necessary for V8Test.OnUncaughtException tests.
settings.uncaught_exception_stack_size = 10;
Implement off-screen rendering support using delegated rendering (issue #1257). This implementation supports both GPU compositing and software compositing (used when GPU is not supported or when passing `--disable-gpu --disable-gpu-compositing` command-line flags). GPU-accelerated features (WebGL and 3D CSS) that did not work with the previous off-screen rendering implementation do work with this implementation when GPU support is available. Rendering now operates on a per-frame basis. The frame rate is configurable via CefBrowserSettings.windowless_frame_rate up to a maximum of 60fps (potentially limited by how fast the system can generate new frames). CEF generates a bitmap from the compositor backing and passes it to CefRenderHandler::OnPaint. The previous CefRenderHandler/CefBrowserHost API for off-screen rendering has been restored mostly as-is with some minor changes: - CefBrowserHost::Invalidate no longer accepts a CefRect region argument. Instead of invalidating a specific region it now triggers generation of a new frame. - The |dirtyRects| argument to CefRenderHandler::OnPaint will now always be a single CefRect representing the whole view (frame) size. Previously, invalidated regions were listed separately. - Linux: CefBrowserHost::SendKeyEvent now expects X11 event information instead of GTK event information. See cefclient for an example of converting GTK events to the necessary format. - Sizes passed to the CefRenderHandler OnPaint and OnPopupSize methods are now already DPI scaled. Previously, the client had to perform DPI scaling. - Includes drag&drop implementation from issue #1032. - Includes unit test fixes from issue #1245. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1751 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
2014-07-01 00:30:29 +02:00
// Necessary for the OSRTest tests.
settings.windowless_rendering_enabled = true;
// For Accept-Language test
CefString(&settings.accept_language_list) = CEF_SETTINGS_ACCEPT_LANGUAGE;
}
void CefTestSuite::RegisterTempDirectory(const CefString& directory) {
base::AutoLock lock_scope(temp_directories_lock_);
temp_directories_.push_back(directory);
}
void CefTestSuite::DeleteTempDirectories() {
base::AutoLock lock_scope(temp_directories_lock_);
for (const auto& temp_directory : temp_directories_) {
CefDeleteFile(temp_directory, true);
}
temp_directories_.clear();
}
void CefTestSuite::PreInitialize() {
#if defined(OS_WIN)
testing::GTEST_FLAG(catch_exceptions) = false;
// Enable termination on heap corruption.
// Ignore the result code. Supported starting with XP SP3 and Vista.
HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0);
#endif
#if defined(OS_LINUX)
// When calling native char conversion functions (e.g wrctomb) we need to
// have the locale set. In the absence of such a call the "C" locale is the
// default. In the gtk code (below) gtk_init() implicitly sets a locale.
setlocale(LC_ALL, "");
#endif // defined(OS_LINUX)
// Don't add additional code to this function. Instead add it to Initialize().
}
void CefTestSuite::Initialize() {
#if defined(OS_WIN)
RouteStdioToConsole(true);
#endif // defined(OS_WIN)
#if !defined(CEF_TESTS_IN_SRC_DIRECTORY)
// Configure the directory that contains test data resources.
std::string resource_dir;
bool result = client::GetResourceDir(resource_dir);
CHECK(result && !resource_dir.empty());
CefSetDataDirectoryForTests(resource_dir);
#endif // !defined(CEF_TESTS_IN_SRC_DIRECTORY)
}
void CefTestSuite::Shutdown() {}