From dcd4a0077c05c0b8ad2e3024e0412ebfd00f80e9 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Tue, 2 Aug 2022 20:51:02 -0400 Subject: [PATCH] Include net test data in the binary distribution (see issue #3348) --- BUILD.gn | 4 ++ cef_paths2.gypi | 13 ++++ cmake/cef_macros.cmake.in | 77 ++++++++++++++--------- include/capi/test/cef_test_helpers_capi.h | 10 ++- include/cef_api_hash.h | 8 +-- include/test/cef_test_helpers.h | 9 +++ libcef/browser/test/test_helpers_impl.cc | 14 +++++ libcef_dll/libcef_dll.cc | 14 ++++- libcef_dll/wrapper/libcef_dll_dylib.cc | 9 ++- libcef_dll/wrapper/libcef_dll_wrapper.cc | 15 ++++- tests/ceftests/CMakeLists.txt.in | 27 +++++++- tests/ceftests/resource_util_win_dir.cc | 34 ++++++++++ tests/ceftests/test_suite.cc | 11 ++++ tests/shared/browser/resource_util.h | 2 - tests/shared/browser/resource_util_mac.mm | 7 ++- tools/distrib/transfer.cfg | 10 ++- 16 files changed, 220 insertions(+), 44 deletions(-) create mode 100644 libcef/browser/test/test_helpers_impl.cc create mode 100644 tests/ceftests/resource_util_win_dir.cc diff --git a/BUILD.gn b/BUILD.gn index da12645a7..9a8048150 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -420,6 +420,7 @@ source_set("libcef_test_support") { testonly = true sources = [ + "libcef/browser/test/test_helpers_impl.cc", "libcef/browser/test/test_server_impl.cc", "libcef/browser/test/test_server_impl.h", "libcef/common/test/translator_test_impl.cc", @@ -2000,6 +2001,7 @@ if (is_mac) { ] helper_defines = [ "CEF_USE_SANDBOX", + "CEF_TESTS_IN_SRC_DIRECTORY", ] info_plist = "tests/ceftests/resources/mac/Info.plist" @@ -2024,6 +2026,7 @@ if (is_mac) { ] defines = [ "CEF_USE_SANDBOX", + "CEF_TESTS_IN_SRC_DIRECTORY", ] } } else { @@ -2247,6 +2250,7 @@ if (is_mac) { defines = [ "CEF_USE_SANDBOX", + "CEF_TESTS_IN_SRC_DIRECTORY", ] if (is_win) { diff --git a/cef_paths2.gypi b/cef_paths2.gypi index 8f82ad714..f42d40929 100644 --- a/cef_paths2.gypi +++ b/cef_paths2.gypi @@ -456,6 +456,10 @@ 'tests/cefsimple/cefsimple_linux.cc', 'tests/cefsimple/simple_handler_linux.cc', ], + 'ceftests_data_resources': [ + 'tests/ceftests/resources/net/data/ssl/certificates/localhost_cert.pem', + 'tests/ceftests/resources/net/data/ssl/certificates/root_ca_cert.pem', + ], 'ceftests_sources_common': [ 'tests/ceftests/audio_output_unittest.cc', 'tests/ceftests/browser_info_map_unittest.cc', @@ -565,6 +569,7 @@ 'tests/ceftests/zip_reader_unittest.cc', ], 'ceftests_sources_win': [ + 'tests/ceftests/resource_util_win_dir.cc', 'tests/ceftests/resource_util_win_idmap.cc', 'tests/ceftests/resources/win/ceftests.rc', ], @@ -618,6 +623,14 @@ 'tests/ceftests/test_request.h', 'tests/ceftests/test_server.cc', 'tests/ceftests/test_server.h', + 'tests/ceftests/test_server_observer.h', + 'tests/ceftests/test_server_observer.cc', + 'tests/ceftests/test_server_manager.h', + 'tests/ceftests/test_server_manager.cc', + 'tests/ceftests/test_server_runner.h', + 'tests/ceftests/test_server_runner.cc', + 'tests/ceftests/test_server_runner_normal.cc', + 'tests/ceftests/test_server_runner_test.cc', 'tests/ceftests/test_suite.cc', 'tests/ceftests/test_suite.h', 'tests/ceftests/test_util.cc', diff --git a/cmake/cef_macros.cmake.in b/cmake/cef_macros.cmake.in index 3ff7c1528..f357d06f6 100644 --- a/cmake/cef_macros.cmake.in +++ b/cmake/cef_macros.cmake.in @@ -95,43 +95,64 @@ macro(SET_CEF_TARGET_OUT_DIR) endif() endmacro() -# Copy a list of files from one directory to another. Relative files paths are maintained. -# The path component of the source |file_list| will be removed. +# Copy a list of files from one directory to another. Relative file paths are maintained. macro(COPY_FILES target file_list source_dir target_dir) foreach(FILENAME ${file_list}) set(source_file ${source_dir}/${FILENAME}) + + # Remove the target file path component. get_filename_component(target_name ${FILENAME} NAME) set(target_file ${target_dir}/${target_name}) - string(FIND ${source_file} "$" _pos) - if(NOT ${_pos} EQUAL -1) - # Must test with an actual configuration directory. - string(REPLACE "$" "Release" existing_source_file ${source_file}) - if(NOT EXISTS ${existing_source_file}) - string(REPLACE "$" "Debug" existing_source_file ${source_file}) - endif() - else() - set(existing_source_file ${source_file}) - endif() - - if(IS_DIRECTORY ${existing_source_file}) - add_custom_command( - TARGET ${target} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory "${source_file}" "${target_file}" - VERBATIM - ) - else() - add_custom_command( - TARGET ${target} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${source_file}" "${target_file}" - VERBATIM - ) - endif() + COPY_SINGLE_FILE(${target} ${source_file} ${target_file}) endforeach() endmacro() +# Copy a list of files from one directory to another. Relative file paths are maintained. +macro(COPY_RESOURCES target file_list prefix_list source_dir target_dir) + foreach(FILENAME ${file_list}) + set(source_file ${source_dir}/${FILENAME}) + + # Remove one or more prefixes from the source paths. + set(TARGET_FILENAME "${FILENAME}") + foreach(PREFIX ${prefix_list}) + string(REGEX REPLACE "^.*${PREFIX}" "" TARGET_FILENAME ${TARGET_FILENAME}) + endforeach() + set(target_file ${target_dir}/${TARGET_FILENAME}) + + COPY_SINGLE_FILE(${target} ${source_file} ${target_file}) + endforeach() +endmacro() + +macro(COPY_SINGLE_FILE target source_file target_file) + string(FIND ${source_file} "$" _pos) + if(NOT ${_pos} EQUAL -1) + # Must test with an actual configuration directory. + string(REPLACE "$" "Release" existing_source_file ${source_file}) + if(NOT EXISTS ${existing_source_file}) + string(REPLACE "$" "Debug" existing_source_file ${source_file}) + endif() + else() + set(existing_source_file ${source_file}) + endif() + + if(IS_DIRECTORY ${existing_source_file}) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory "${source_file}" "${target_file}" + VERBATIM + ) + else() + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${source_file}" "${target_file}" + VERBATIM + ) + endif() +endmacro() + # # Linux macros. diff --git a/include/capi/test/cef_test_helpers_capi.h b/include/capi/test/cef_test_helpers_capi.h index 128ab4c64..b952d5528 100644 --- a/include/capi/test/cef_test_helpers_capi.h +++ b/include/capi/test/cef_test_helpers_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=584acfdb7be699b0192c46ac9fa88084f141e845$ +// $hash=20fc4636e154ab38b79287c29f8f7f22e3cd8d37$ // #ifndef CEF_INCLUDE_CAPI_TEST_CEF_TEST_HELPERS_CAPI_H_ @@ -59,6 +59,14 @@ CEF_EXPORT void cef_execute_java_script_with_user_gesture_for_tests( struct _cef_frame_t* frame, const cef_string_t* javascript); +/// +// Set the DIR_SRC_TEST_DATA_ROOT directory used to load test data. Must be +// configured when running from a CEF binary distribution. Defaults to the +// "chromium/src" directory when running from a local CEF/Chromium build. |dir| +// must be an absolute path. +/// +CEF_EXPORT void cef_set_data_directory_for_tests(const cef_string_t* dir); + #ifdef __cplusplus } #endif diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index 15df38240..d4bdfca20 100644 --- a/include/cef_api_hash.h +++ b/include/cef_api_hash.h @@ -42,13 +42,13 @@ // way that may cause binary incompatibility with other builds. The universal // hash value will change if any platform is affected whereas the platform hash // values will change only if that particular platform is affected. -#define CEF_API_HASH_UNIVERSAL "75e20201c2d8df3e03f2c8e285d348ef9748ec52" +#define CEF_API_HASH_UNIVERSAL "44bd5636f7e831a459d22b9b28ed8bfe233e88b2" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "8ade85f2430574759f46159d4e1b58758d7e69c8" +#define CEF_API_HASH_PLATFORM "31c7becd3dfaad2dd49331127ae3b15cf20677d8" #elif defined(OS_MAC) -#define CEF_API_HASH_PLATFORM "3cd04d7d724ad382f1647b93b81e3ab59ab18db6" +#define CEF_API_HASH_PLATFORM "33a65ab4d7adf95184cfc6216d9101360ec55d07" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "1fe0b7b127d115c74650d21a408cfa08d83418e8" +#define CEF_API_HASH_PLATFORM "1bae56c928de4d52851dc312cde21d31b776dcfb" #endif #ifdef __cplusplus diff --git a/include/test/cef_test_helpers.h b/include/test/cef_test_helpers.h index a4e45b8e4..9bcd7831e 100644 --- a/include/test/cef_test_helpers.h +++ b/include/test/cef_test_helpers.h @@ -58,4 +58,13 @@ void CefExecuteJavaScriptWithUserGestureForTests(CefRefPtr frame, const CefString& javascript); +/// +// Set the DIR_SRC_TEST_DATA_ROOT directory used to load test data. Must be +// configured when running from a CEF binary distribution. Defaults to the +// "chromium/src" directory when running from a local CEF/Chromium build. |dir| +// must be an absolute path. +/// +/*--cef()--*/ +void CefSetDataDirectoryForTests(const CefString& dir); + #endif // CEF_INCLUDE_TEST_CEF_TEST_HELPERS_H_ diff --git a/libcef/browser/test/test_helpers_impl.cc b/libcef/browser/test/test_helpers_impl.cc new file mode 100644 index 000000000..1e0ea9c10 --- /dev/null +++ b/libcef/browser/test/test_helpers_impl.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2022 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 "include/test/cef_test_helpers.h" + +#include "base/files/file_path.h" +#include "base/path_service.h" + +void CefSetDataDirectoryForTests(const CefString& dir) { + base::PathService::OverrideAndCreateIfNeeded( + base::DIR_SRC_TEST_DATA_ROOT, base::FilePath(dir), /*is_absolute=*/true, + /*create=*/false); +} diff --git a/libcef_dll/libcef_dll.cc b/libcef_dll/libcef_dll.cc index 05b1cc586..c54750e48 100644 --- a/libcef_dll/libcef_dll.cc +++ b/libcef_dll/libcef_dll.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=6f8f05ae0e6a0b4122af70f11e6f14f2c3bbff6f$ +// $hash=70f3e95dc09c7676072c8f8ecae04a9c631523ee$ // #include "include/capi/cef_app_capi.h" @@ -860,3 +860,15 @@ CEF_EXPORT void cef_execute_java_script_with_user_gesture_for_tests( CefExecuteJavaScriptWithUserGestureForTests(CefFrameCppToC::Unwrap(frame), CefString(javascript)); } + +CEF_EXPORT void cef_set_data_directory_for_tests(const cef_string_t* dir) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: dir; type: string_byref_const + DCHECK(dir); + if (!dir) + return; + + // Execute + CefSetDataDirectoryForTests(CefString(dir)); +} diff --git a/libcef_dll/wrapper/libcef_dll_dylib.cc b/libcef_dll/wrapper/libcef_dll_dylib.cc index 937f5e359..32b8b1256 100644 --- a/libcef_dll/wrapper/libcef_dll_dylib.cc +++ b/libcef_dll/wrapper/libcef_dll_dylib.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=5bba27a98f6ef56e7577c563084beb0f185cf164$ +// $hash=b0d09c42b0c401cc3e9a8f0cfe93e464c6b7b34c$ // #include @@ -144,6 +144,7 @@ struct libcef_pointers { decltype(&cef_register_extension) cef_register_extension; decltype(&cef_execute_java_script_with_user_gesture_for_tests) cef_execute_java_script_with_user_gesture_for_tests; + decltype(&cef_set_data_directory_for_tests) cef_set_data_directory_for_tests; decltype(&cef_browser_host_create_browser) cef_browser_host_create_browser; decltype(&cef_browser_host_create_browser_sync) cef_browser_host_create_browser_sync; @@ -371,6 +372,7 @@ int libcef_init_pointers(const char* path) { INIT_ENTRY(cef_now_from_system_trace_time); INIT_ENTRY(cef_register_extension); INIT_ENTRY(cef_execute_java_script_with_user_gesture_for_tests); + INIT_ENTRY(cef_set_data_directory_for_tests); INIT_ENTRY(cef_browser_host_create_browser); INIT_ENTRY(cef_browser_host_create_browser_sync); INIT_ENTRY(cef_command_line_create); @@ -828,6 +830,11 @@ void cef_execute_java_script_with_user_gesture_for_tests( frame, javascript); } +NO_SANITIZE("cfi-icall") +void cef_set_data_directory_for_tests(const cef_string_t* dir) { + g_libcef_pointers.cef_set_data_directory_for_tests(dir); +} + NO_SANITIZE("cfi-icall") int cef_browser_host_create_browser( const struct _cef_window_info_t* windowInfo, diff --git a/libcef_dll/wrapper/libcef_dll_wrapper.cc b/libcef_dll/wrapper/libcef_dll_wrapper.cc index 38eec0c0e..cf70644c1 100644 --- a/libcef_dll/wrapper/libcef_dll_wrapper.cc +++ b/libcef_dll/wrapper/libcef_dll_wrapper.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=b0db26b4749beed24b02af98543422f489e0a0a8$ +// $hash=52ee2d630fed6972270fa16ca2ad5c474f723da1$ // #include "include/capi/cef_app_capi.h" @@ -818,3 +818,16 @@ CEF_GLOBAL void CefExecuteJavaScriptWithUserGestureForTests( cef_execute_java_script_with_user_gesture_for_tests( CefFrameCToCpp::Unwrap(frame), javascript.GetStruct()); } + +NO_SANITIZE("cfi-icall") +CEF_GLOBAL void CefSetDataDirectoryForTests(const CefString& dir) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: dir; type: string_byref_const + DCHECK(!dir.empty()); + if (dir.empty()) + return; + + // Execute + cef_set_data_directory_for_tests(dir.GetStruct()); +} diff --git a/tests/ceftests/CMakeLists.txt.in b/tests/ceftests/CMakeLists.txt.in index 9ce0f99bc..f5a418b7c 100644 --- a/tests/ceftests/CMakeLists.txt.in +++ b/tests/ceftests/CMakeLists.txt.in @@ -47,6 +47,14 @@ ], }} +# ceftests data resources. +{{ + 'prefix': 'ceftests_data_resources', + 'set': 'UNITTESTS_DATA_RESOURCES_SRCS', + 'includes': [ + 'ceftests_data_resources', + ], +}} # # Shared configuration. @@ -92,6 +100,13 @@ if(OS_LINUX) # Copy ceftests resource files to the target output directory. COPY_FILES("${CEF_TARGET}" "${UNITTESTS_RESOURCES_SRCS}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_TARGET_OUT_DIR}/ceftests_files") + # Copy ceftests data resource files to the target output directory. + # Remove these prefixes from input file paths. + set(PREFIXES + "resources/" + ) + COPY_RESOURCES("${CEF_TARGET}" "${UNITTESTS_DATA_RESOURCES_SRCS}" "${PREFIXES}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_TARGET_OUT_DIR}/ceftests_files") + # Set SUID permissions on the chrome-sandbox target. SET_LINUX_SUID_PERMISSIONS("${CEF_TARGET}" "${CEF_TARGET_OUT_DIR}/chrome-sandbox") endif() @@ -190,9 +205,11 @@ if(OS_MAC) # Remove these prefixes from input file paths. set(PREFIXES "resources/mac/" + "resources/" "../shared/resources/" ) - COPY_MAC_RESOURCES("${UNITTESTS_RESOURCES_SRCS}" "${PREFIXES}" "${CEF_TARGET}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_APP}") + set(RESOURCES ${UNITTESTS_RESOURCES_SRCS} ${UNITTESTS_DATA_RESOURCES_SRCS}) + COPY_MAC_RESOURCES("${RESOURCES}" "${PREFIXES}" "${CEF_TARGET}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_APP}") endif() @@ -224,5 +241,11 @@ if(OS_WINDOWS) # Copy CEF binary and resource files to the target output directory. COPY_FILES("${CEF_TARGET}" "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${CEF_TARGET_OUT_DIR}") COPY_FILES("${CEF_TARGET}" "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${CEF_TARGET_OUT_DIR}") -endif() + # Copy ceftests data resource files to the target output directory. + # Remove these prefixes from input file paths. + set(PREFIXES + "resources/" + ) + COPY_RESOURCES("${CEF_TARGET}" "${UNITTESTS_DATA_RESOURCES_SRCS}" "${PREFIXES}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_TARGET_OUT_DIR}/ceftests_files") +endif() diff --git a/tests/ceftests/resource_util_win_dir.cc b/tests/ceftests/resource_util_win_dir.cc new file mode 100644 index 000000000..2bd3200f3 --- /dev/null +++ b/tests/ceftests/resource_util_win_dir.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2022 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 "tests/shared/browser/resource_util.h" + +#include + +#include "include/internal/cef_string_wrappers.h" + +namespace client { + +bool GetResourceDir(std::string& dir) { + wchar_t buff[MAX_PATH]; + + // Retrieve the executable path. + auto len = GetModuleFileName(nullptr, buff, MAX_PATH); + if (len == 0) + return false; + + buff[len] = 0; + + // Remove the executable name from the path. + auto* pos = wcsrchr(buff, L'\\'); + if (!pos) + return false; + + // Add "ceftests_files" to the path. + wcscpy(pos + 1, L"ceftests_files"); + dir = CefStringWide(buff).ToString(); + return true; +} + +} // namespace client diff --git a/tests/ceftests/test_suite.cc b/tests/ceftests/test_suite.cc index 47d796e2c..9c7354200 100644 --- a/tests/ceftests/test_suite.cc +++ b/tests/ceftests/test_suite.cc @@ -4,10 +4,13 @@ #include "tests/ceftests/test_suite.h" +#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 { @@ -203,6 +206,14 @@ 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() {} diff --git a/tests/shared/browser/resource_util.h b/tests/shared/browser/resource_util.h index cf4e5af0a..0e03eb7b3 100644 --- a/tests/shared/browser/resource_util.h +++ b/tests/shared/browser/resource_util.h @@ -16,10 +16,8 @@ namespace client { -#if defined(OS_POSIX) // Returns the directory containing resource files. bool GetResourceDir(std::string& dir); -#endif // Retrieve a resource as a string. bool LoadBinaryResource(const char* resource_name, std::string& resource_data); diff --git a/tests/shared/browser/resource_util_mac.mm b/tests/shared/browser/resource_util_mac.mm index d2998cb3a..72e88d9b7 100644 --- a/tests/shared/browser/resource_util_mac.mm +++ b/tests/shared/browser/resource_util_mac.mm @@ -39,10 +39,11 @@ bool GetResourceDir(std::string& dir) { if (AmIBundled()) { // Trim executable name up to the last separator. - std::string::size_type last_separator = dir.find_last_of("/"); + auto last_separator = dir.find_last_of("/"); + dir.resize(last_separator); + // Trim directory ("MacOS") up to the last separator. + last_separator = dir.find_last_of("/"); dir.resize(last_separator); - dir.append("/../Resources"); - return true; } dir.append("/Resources"); diff --git a/tools/distrib/transfer.cfg b/tools/distrib/transfer.cfg index 6b8a5cdaa..be8932172 100644 --- a/tools/distrib/transfer.cfg +++ b/tools/distrib/transfer.cfg @@ -14,4 +14,12 @@ 'source' : '../net/base/net_error_list.h', 'target' : 'include/base/internal/cef_net_error_list.h', }, -] \ No newline at end of file + { + 'source' : '../net/data/ssl/certificates/localhost_cert.pem', + 'target' : 'tests/ceftests/resources/net/data/ssl/certificates/localhost_cert.pem', + }, + { + 'source' : '../net/data/ssl/certificates/root_ca_cert.pem', + 'target' : 'tests/ceftests/resources/net/data/ssl/certificates/root_ca_cert.pem', + }, +]