cef/tests/ceftests/run_all_unittests.cc

306 lines
8.9 KiB
C++
Raw Permalink Normal View History

// Copyright (c) 2012 The Chromium Embedded Framework 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 <memory>
#include "include/base/cef_build.h"
#if defined(OS_LINUX) && defined(CEF_X11)
#include <X11/Xlib.h>
// Definitions conflict with gtest.
#undef None
#undef Bool
#endif
#if defined(OS_POSIX)
#include <unistd.h>
#endif
#include "include/base/cef_callback.h"
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
#include "include/cef_api_hash.h"
#include "include/cef_app.h"
#include "include/cef_task.h"
2016-11-11 18:22:53 -05:00
#include "include/cef_thread.h"
#include "include/cef_waitable_event.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h"
#include "tests/ceftests/test_handler.h"
#include "tests/ceftests/test_server.h"
#include "tests/ceftests/test_suite.h"
chrome: Add support for Alloy style browsers and windows (see #3681) Split the Alloy runtime into bootstrap and style components. Support creation of Alloy style browsers and windows with the Chrome runtime. Chrome runtime (`--enable-chrome-runtime`) + Alloy style (`--use-alloy-style`) supports Views (`--use-views`), native parent (`--use-native`) and windowless rendering (`--off-screen-rendering-enabled`). Print preview is supported in all cases except with windowless rendering on all platforms and native parent on MacOS. It is disabled by default with Alloy style for legacy compatibility. Where supported it can be enabled or disabled globally using `--[enable|disable]-print-preview` or configured on a per-RequestContext basis using the `printing.print_preview_disabled` preference. It also behaves as expected when triggered via the PDF viewer print button. Chrome runtime + Alloy style behavior differs from Alloy runtime in the following significant ways: - Supports Chrome error pages by default. - DevTools popups are Chrome style only (cannot be windowless). - The Alloy extension API will not supported. Chrome runtime + Alloy style passes all expected Alloy ceftests except the following: - `DisplayTest.AutoResize` (Alloy extension API not supported) - `DownloadTest.*` (Download API not yet supported) - `ExtensionTest.*` (Alloy extension API not supported) This change also adds Chrome runtime support for CefContextMenuHandler::RunContextMenu (see #3293). This change also explicitly blocks (and doesn't retry) FrameAttached requests from PDF viewer and print preview excluded frames (see #3664). Known issues specific to Chrome runtime + Alloy style: - DevTools popup with windowless rendering doesn't load successfully. Use windowed rendering or remote debugging as a workaround. - Chrome style Window with Alloy style BrowserView (`--use-alloy-style --use-chrome-style-window`) does not show Chrome theme changes. To test: - Run `ceftests --enable-chrome-runtime --use-alloy-style [--use-chrome-style-window] [--use-views|--use-native] --gtest_filter=...` - Run `cefclient --enable-chrome-runtime --use-alloy-style [--use-chrome-style-window] [--use-views|--use-native|--off-screen-rendering-enabled]` - Run `cefsimple --enable-chrome-runtime --use-alloy-style [--use-views]`
2024-04-17 12:01:26 -04:00
#include "tests/ceftests/test_util.h"
#include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/browser/main_message_loop_external_pump.h"
#include "tests/shared/browser/main_message_loop_std.h"
#include "tests/shared/common/client_app_other.h"
#include "tests/shared/renderer/client_app_renderer.h"
#if defined(OS_MAC)
#include "include/wrapper/cef_library_loader.h"
#endif
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically if using the required compiler version. Pass -DUSE_SANDBOX=OFF
// to the CMake command-line to disable use of the sandbox.
#if defined(OS_WIN) && defined(CEF_USE_SANDBOX)
#include "include/cef_sandbox_win.h"
// The cef_sandbox.lib static library may not link successfully with all VS
// versions.
#pragma comment(lib, "cef_sandbox.lib")
#endif
#if defined(OS_MAC)
// Platform-specific initialization and cleanup.
extern void PlatformInit();
extern void PlatformCleanup();
#endif
namespace {
void QuitMessageLoop() {
CEF_REQUIRE_UI_THREAD();
client::MainMessageLoop* message_loop = client::MainMessageLoop::Get();
2023-01-02 17:59:03 -05:00
if (message_loop) {
message_loop->Quit();
2023-01-02 17:59:03 -05:00
} else {
CefQuitMessageLoop();
2023-01-02 17:59:03 -05:00
}
}
void sleep(int64_t ms) {
#if defined(OS_WIN)
Sleep(ms);
#elif defined(OS_POSIX)
usleep(static_cast<useconds_t>(ms * 1000));
#else
#error Unsupported platform
#endif
}
// Called on the test thread.
void RunTestsOnTestThread() {
2016-11-11 18:22:53 -05:00
// Run the test suite.
CefTestSuite::GetInstance()->Run();
// Wait for all TestHandlers to be destroyed.
size_t loop_count = 0;
while (true) {
const size_t handler_count = TestHandler::GetTestHandlerCount();
if (handler_count == 0) {
break;
}
if (++loop_count == 20) {
LOG(ERROR) << "Terminating with " << handler_count
<< " leaked TestHandler objects";
break;
}
sleep(100);
2023-01-02 17:59:03 -05:00
}
// Wait for the test server to stop, and then quit the CEF message loop.
test_server::Stop(base::BindOnce(QuitMessageLoop));
2016-11-11 18:22:53 -05:00
}
// Called on the UI thread.
void ContinueOnUIThread(CefRefPtr<CefTaskRunner> test_task_runner) {
// Run the test suite on the test thread.
2016-11-11 18:22:53 -05:00
test_task_runner->PostTask(
CefCreateClosureTask(base::BindOnce(&RunTestsOnTestThread)));
}
#if defined(OS_LINUX) && defined(CEF_X11)
int XErrorHandlerImpl(Display* display, XErrorEvent* event) {
LOG(WARNING) << "X error received: " << "type " << event->type << ", "
<< "serial " << event->serial << ", " << "error_code "
<< static_cast<int>(event->error_code) << ", " << "request_code "
<< static_cast<int>(event->request_code) << ", " << "minor_code "
<< static_cast<int>(event->minor_code);
return 0;
}
int XIOErrorHandlerImpl(Display* display) {
return 0;
}
#endif // defined(OS_LINUX) && defined(CEF_X11)
#if defined(OS_MAC)
class ScopedPlatformSetup final {
public:
ScopedPlatformSetup() { PlatformInit(); }
~ScopedPlatformSetup() { PlatformCleanup(); }
};
#endif // defined(OS_MAC)
} // namespace
int main(int argc, char* argv[]) {
int exit_code;
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
#if CEF_API_VERSION != CEF_EXPERIMENTAL
printf("Running with configured CEF API version %d\n", CEF_API_VERSION);
#endif
#if defined(OS_WIN) && defined(ARCH_CPU_32_BITS)
// Run the main thread on 32-bit Windows using a fiber with the preferred 4MiB
// stack size. This function must be called at the top of the executable entry
// point function (`main()` or `wWinMain()`). It is used in combination with
// the initial stack size of 0.5MiB configured via the `/STACK:0x80000` linker
// flag on executable targets. This saves significant memory on threads (like
// those in the Windows thread pool, and others) whose stack size can only be
// controlled via the linker flag.
exit_code = CefRunMainWithPreferredStackSize(main, argc, argv);
if (exit_code >= 0) {
// The fiber has completed so return here.
return exit_code;
}
#endif
#if defined(OS_MAC)
// Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader;
2023-01-02 17:59:03 -05:00
if (!library_loader.LoadInMain()) {
return 1;
2023-01-02 17:59:03 -05:00
}
#endif
// Create the singleton test suite object.
CefTestSuite test_suite(argc, argv);
#if defined(OS_WIN)
CefMainArgs main_args(::GetModuleHandle(nullptr));
#else
CefMainArgs main_args(argc, argv);
#endif
void* windows_sandbox_info = nullptr;
#if defined(OS_WIN) && defined(CEF_USE_SANDBOX)
// Manages the life span of the sandbox information object.
CefScopedSandboxInfo scoped_sandbox;
windows_sandbox_info = scoped_sandbox.sandbox_info();
#endif
// Create a ClientApp of the correct type.
CefRefPtr<CefApp> app;
client::ClientApp::ProcessType process_type =
client::ClientApp::GetProcessType(test_suite.command_line());
if (process_type == client::ClientApp::BrowserProcess) {
app = new client::ClientAppBrowser();
#if !defined(OS_MAC)
} else if (process_type == client::ClientApp::RendererProcess ||
process_type == client::ClientApp::ZygoteProcess) {
app = new client::ClientAppRenderer();
} else if (process_type == client::ClientApp::OtherProcess) {
app = new client::ClientAppOther();
}
// Execute the secondary process, if any.
exit_code = CefExecuteProcess(main_args, app, windows_sandbox_info);
2023-01-02 17:59:03 -05:00
if (exit_code >= 0) {
return exit_code;
2023-01-02 17:59:03 -05:00
}
#else
} else {
// On MacOS this executable is only used for the main process.
NOTREACHED();
}
#endif
CefSettings settings;
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
client::ClientAppBrowser::PopulateSettings(test_suite.command_line(),
settings);
test_suite.GetSettings(settings);
#if defined(OS_MAC)
ScopedPlatformSetup scoped_platform_setup;
#endif
#if defined(OS_LINUX) && defined(CEF_X11)
// Install xlib error handlers so that the application won't be terminated
// on non-fatal errors.
XSetErrorHandler(XErrorHandlerImpl);
XSetIOErrorHandler(XIOErrorHandlerImpl);
#endif
// Initialize CEF.
if (!CefInitialize(main_args, settings, app, windows_sandbox_info)) {
exit_code = CefGetExitCode();
LOG(ERROR) << "CefInitialize exited with code " << exit_code;
return exit_code;
}
chrome: Add support for Alloy style browsers and windows (see #3681) Split the Alloy runtime into bootstrap and style components. Support creation of Alloy style browsers and windows with the Chrome runtime. Chrome runtime (`--enable-chrome-runtime`) + Alloy style (`--use-alloy-style`) supports Views (`--use-views`), native parent (`--use-native`) and windowless rendering (`--off-screen-rendering-enabled`). Print preview is supported in all cases except with windowless rendering on all platforms and native parent on MacOS. It is disabled by default with Alloy style for legacy compatibility. Where supported it can be enabled or disabled globally using `--[enable|disable]-print-preview` or configured on a per-RequestContext basis using the `printing.print_preview_disabled` preference. It also behaves as expected when triggered via the PDF viewer print button. Chrome runtime + Alloy style behavior differs from Alloy runtime in the following significant ways: - Supports Chrome error pages by default. - DevTools popups are Chrome style only (cannot be windowless). - The Alloy extension API will not supported. Chrome runtime + Alloy style passes all expected Alloy ceftests except the following: - `DisplayTest.AutoResize` (Alloy extension API not supported) - `DownloadTest.*` (Download API not yet supported) - `ExtensionTest.*` (Alloy extension API not supported) This change also adds Chrome runtime support for CefContextMenuHandler::RunContextMenu (see #3293). This change also explicitly blocks (and doesn't retry) FrameAttached requests from PDF viewer and print preview excluded frames (see #3664). Known issues specific to Chrome runtime + Alloy style: - DevTools popup with windowless rendering doesn't load successfully. Use windowed rendering or remote debugging as a workaround. - Chrome style Window with Alloy style BrowserView (`--use-alloy-style --use-chrome-style-window`) does not show Chrome theme changes. To test: - Run `ceftests --enable-chrome-runtime --use-alloy-style [--use-chrome-style-window] [--use-views|--use-native] --gtest_filter=...` - Run `cefclient --enable-chrome-runtime --use-alloy-style [--use-chrome-style-window] [--use-views|--use-native|--off-screen-rendering-enabled]` - Run `cefsimple --enable-chrome-runtime --use-alloy-style [--use-views]`
2024-04-17 12:01:26 -04:00
// Log the current configuration.
2024-06-25 20:12:37 -04:00
LOG(WARNING)
<< "Using " << (UseAlloyStyleBrowserGlobal() ? "Alloy" : "Chrome")
<< " style browser; "
<< (UseViewsGlobal()
? (std::string(UseAlloyStyleWindowGlobal() ? "Alloy" : "Chrome") +
" style window; ")
: "")
<< (UseViewsGlobal() ? "Views" : "Native") << "-hosted (not a warning)";
chrome: Add support for Alloy style browsers and windows (see #3681) Split the Alloy runtime into bootstrap and style components. Support creation of Alloy style browsers and windows with the Chrome runtime. Chrome runtime (`--enable-chrome-runtime`) + Alloy style (`--use-alloy-style`) supports Views (`--use-views`), native parent (`--use-native`) and windowless rendering (`--off-screen-rendering-enabled`). Print preview is supported in all cases except with windowless rendering on all platforms and native parent on MacOS. It is disabled by default with Alloy style for legacy compatibility. Where supported it can be enabled or disabled globally using `--[enable|disable]-print-preview` or configured on a per-RequestContext basis using the `printing.print_preview_disabled` preference. It also behaves as expected when triggered via the PDF viewer print button. Chrome runtime + Alloy style behavior differs from Alloy runtime in the following significant ways: - Supports Chrome error pages by default. - DevTools popups are Chrome style only (cannot be windowless). - The Alloy extension API will not supported. Chrome runtime + Alloy style passes all expected Alloy ceftests except the following: - `DisplayTest.AutoResize` (Alloy extension API not supported) - `DownloadTest.*` (Download API not yet supported) - `ExtensionTest.*` (Alloy extension API not supported) This change also adds Chrome runtime support for CefContextMenuHandler::RunContextMenu (see #3293). This change also explicitly blocks (and doesn't retry) FrameAttached requests from PDF viewer and print preview excluded frames (see #3664). Known issues specific to Chrome runtime + Alloy style: - DevTools popup with windowless rendering doesn't load successfully. Use windowed rendering or remote debugging as a workaround. - Chrome style Window with Alloy style BrowserView (`--use-alloy-style --use-chrome-style-window`) does not show Chrome theme changes. To test: - Run `ceftests --enable-chrome-runtime --use-alloy-style [--use-chrome-style-window] [--use-views|--use-native] --gtest_filter=...` - Run `cefclient --enable-chrome-runtime --use-alloy-style [--use-chrome-style-window] [--use-views|--use-native|--off-screen-rendering-enabled]` - Run `cefsimple --enable-chrome-runtime --use-alloy-style [--use-views]`
2024-04-17 12:01:26 -04:00
std::unique_ptr<client::MainMessageLoop> message_loop;
// Initialize the testing framework.
test_suite.InitMainProcess();
int retval;
if (settings.multi_threaded_message_loop) {
// Run the test suite on the main thread.
retval = test_suite.Run();
// Wait for the test server to stop.
CefRefPtr<CefWaitableEvent> event =
CefWaitableEvent::CreateWaitableEvent(true, false);
test_server::Stop(base::BindOnce(&CefWaitableEvent::Signal, event));
event->Wait();
} else {
2016-11-11 18:22:53 -05:00
// Create and start the test thread.
CefRefPtr<CefThread> thread = CefThread::CreateThread("test_thread");
2023-01-02 17:59:03 -05:00
if (!thread) {
LOG(ERROR) << "test_thread creation failed";
return 1;
2023-01-02 17:59:03 -05:00
}
// Start the tests from the UI thread so that any pending UI tasks get a
// chance to execute first.
2016-11-11 18:22:53 -05:00
CefPostTask(TID_UI,
base::BindOnce(&ContinueOnUIThread, thread->GetTaskRunner()));
// Create the CEF message loop.
if (settings.external_message_pump) {
message_loop = client::MainMessageLoopExternalPump::Create();
} else {
message_loop = std::make_unique<client::MainMessageLoopStd>();
}
// Run the CEF message loop.
message_loop->Run();
// The test suite has completed.
retval = test_suite.retval();
// Terminate the test thread.
2016-11-11 18:22:53 -05:00
thread->Stop();
thread = nullptr;
}
// Shut down CEF.
CefShutdown();
test_suite.DeleteTempDirectories();
// Destroy the CEF message loop, if any.
message_loop.reset(nullptr);
return retval;
}