Tests: add option to build one binary per GTest file

Bundling many tests in a single binary reduces build time and disk space
usage, but is less convenient for running individual tests command line
as filter flags need to be used.

This adds WITH_TESTS_SINGLE_BINARY to generate one executable file per
source file. Note that enabling this option requires a significant amount
of disk space.

Due to refactoring, the resulting ctest names are a bit different than
before. The number of tests is also a bit different depending if this
option is used, as one uses gtests discovery and the other is organized
purely by filename, which isn't always 1:1.

Co-authored-by: Sergey Sharybin <sergey@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/114604
This commit is contained in:
Brecht Van Lommel 2024-01-03 18:35:50 +01:00 committed by Brecht Van Lommel
parent 81017772f5
commit 364beee159
31 changed files with 330 additions and 181 deletions

@ -781,6 +781,13 @@ endif()
option(WITH_TESTS_BATCHED "Run multiple tests in a single Blender invocation, for faster test execution" ON)
mark_as_advanced(WITH_TESTS_BATCHED)
option(WITH_TESTS_SINGLE_BINARY "\
Link GTest tests into a single binary. \
For faster overall build and less disk space, but slower individual test build"
ON
)
mark_as_advanced(WITH_TESTS_SINGLE_BINARY)
# NOTE: All callers of this must add `TEST_PYTHON_EXE_EXTRA_ARGS` before any other arguments.
set(TEST_PYTHON_EXE "" CACHE PATH "Python executable to run unit tests")
mark_as_advanced(TEST_PYTHON_EXE)

@ -14,7 +14,7 @@ endfunction()
macro(blender_src_gtest_ex)
if(WITH_GTESTS)
set(options SKIP_ADD_TEST)
set(options)
set(oneValueArgs NAME)
set(multiValueArgs SRC EXTRA_LIBS COMMAND_ARGS)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
@ -87,21 +87,6 @@ macro(blender_src_gtest_ex)
RUNTIME_OUTPUT_DIRECTORY "${TESTS_OUTPUT_DIR}"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${TESTS_OUTPUT_DIR}"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${TESTS_OUTPUT_DIR}")
if(NOT ARG_SKIP_ADD_TEST)
add_test(
NAME ${TARGET_NAME}
COMMAND ${TESTS_OUTPUT_DIR}/${TARGET_NAME} ${ARG_COMMAND_ARGS}
WORKING_DIRECTORY ${TEST_INSTALL_DIR})
# Don't fail tests on leaks since these often happen in external libraries
# that we can't fix.
set_tests_properties(${TARGET_NAME} PROPERTIES
ENVIRONMENT LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS}
)
if(WIN32)
set_tests_properties(${TARGET_NAME} PROPERTIES ENVIRONMENT "PATH=${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/blender.shared/;$ENV{PATH}")
endif()
endif()
if(WIN32)
set_target_properties(${TARGET_NAME} PROPERTIES VS_GLOBAL_VcpkgEnabled "false")
endif()
@ -112,13 +97,13 @@ macro(blender_src_gtest_ex)
endif()
endmacro()
function(blender_add_test_suite)
function(blender_add_ctests)
if(ARGC LESS 1)
message(FATAL_ERROR "No arguments supplied to blender_add_test_suite()")
message(FATAL_ERROR "No arguments supplied to blender_add_ctests()")
endif()
# Parse the arguments
set(oneValueArgs TARGET SUITE_NAME)
set(oneValueArgs DISCOVER_TESTS TARGET SUITE_NAME)
set(multiValueArgs SOURCES)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
@ -135,16 +120,27 @@ function(blender_add_test_suite)
endif()
# Define a test case with our custom gtest_add_tests() command.
include(GTest)
gtest_add_tests(
TARGET ${ARGS_TARGET}
SOURCES "${ARGS_SOURCES}"
TEST_PREFIX ${ARGS_SUITE_NAME}
WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
EXTRA_ARGS
--test-assets-dir "${CMAKE_SOURCE_DIR}/../lib/tests"
--test-release-dir "${_test_release_dir}"
)
if(${ARGS_DISCOVER_TESTS})
include(GTest)
gtest_add_tests(
TARGET ${ARGS_TARGET}
SOURCES "${ARGS_SOURCES}"
TEST_PREFIX ${ARGS_SUITE_NAME}
WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
EXTRA_ARGS
--test-assets-dir "${CMAKE_SOURCE_DIR}/../lib/tests"
--test-release-dir "${_test_release_dir}"
)
else()
add_test(
NAME ${ARGS_SUITE_NAME}
COMMAND ${ARGS_TARGET}
--test-assets-dir "${CMAKE_SOURCE_DIR}/../lib/tests"
--test-release-dir "${_test_release_dir}"
WORKING_DIRECTORY ${TEST_INSTALL_DIR}
)
endif()
if(WIN32)
set_tests_properties(
${ARGS_SUITE_NAME} PROPERTIES
@ -155,8 +151,17 @@ function(blender_add_test_suite)
endfunction()
# Add tests for a Blender library, to be called in tandem with blender_add_lib().
# The tests will be part of the blender_test executable (see tests/gtests/runner).
function(blender_add_test_lib
#
# If WITH_TESTS_SINGLE_BINARY is enabled, tests will be put into the blender_test
# executable, and a separate ctest will be generated for every gtest contained in it.
#
# If WITH_TESTS_SINGLE_BINARY is disabled, this works identically to
# blender_add_test_suite_executable.
#
# The function accepts an optional argument which denotes list of sources which
# is to be compiled-in with the suite sources for each fo the suites when the
# WITH_TESTS_SINGLE_BINARY configuration is set to OFF.
function(blender_add_test_suite_lib
name
sources
includes
@ -164,53 +169,66 @@ function(blender_add_test_lib
library_deps
)
add_cc_flags_custom_test(${name} PARENT_SCOPE)
# Sources which are common for all suits and do not need to yield their own
# test suite binaries when WITH_TESTS_SINGLE_BINARY is OFF.
set(common_sources ${ARGN})
# Otherwise external projects will produce warnings that we cannot fix.
remove_strict_flags()
if(WITH_TESTS_SINGLE_BINARY)
add_cc_flags_custom_test(${name}_tests PARENT_SCOPE)
# This duplicates logic that's also in blender_src_gtest_ex.
# TODO(Sybren): deduplicate after the general approach in D7649 has been approved.
list(APPEND includes
${CMAKE_SOURCE_DIR}/tests/gtests
)
list(APPEND includes_sys
${GLOG_INCLUDE_DIRS}
${GFLAGS_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/extern/gtest/include
${CMAKE_SOURCE_DIR}/extern/gmock/include
)
# Otherwise external projects will produce warnings that we cannot fix.
remove_strict_flags()
blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
# This duplicates logic that's also in blender_src_gtest_ex.
# TODO(Sybren): deduplicate after the general approach in D7649 has been approved.
list(APPEND includes
${CMAKE_SOURCE_DIR}/tests/gtests
)
list(APPEND includes_sys
${GLOG_INCLUDE_DIRS}
${GFLAGS_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/extern/gtest/include
${CMAKE_SOURCE_DIR}/extern/gmock/include
)
target_compile_definitions(${name} PRIVATE ${GFLAGS_DEFINES})
target_compile_definitions(${name} PRIVATE ${GLOG_DEFINES})
blender_add_lib__impl(${name}_tests
"${sources};${common_sources}" "${includes}" "${includes_sys}" "${library_deps}")
set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name})
target_compile_definitions(${name}_tests PRIVATE ${GFLAGS_DEFINES})
target_compile_definitions(${name}_tests PRIVATE ${GLOG_DEFINES})
blender_add_test_suite(
TARGET blender_test
SUITE_NAME ${name}
SOURCES "${sources}"
)
set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name}_tests)
blender_add_ctests(
TARGET blender_test
SUITE_NAME ${name}
SOURCES "${sources};${common_sources}"
DISCOVER_TESTS TRUE
)
else()
blender_add_test_suite_executable(
"${name}"
"${sources}"
"${includes}"
"${includes_sys}"
"${library_deps}"
"${common_sources}"
)
endif()
endfunction()
# Add tests for a Blender library, to be called in tandem with blender_add_lib().
# Test will be compiled into a ${name}_test executable.
#
# To be used for smaller isolated libraries, that do not have many dependencies.
# For libraries that do drag in many other Blender libraries and would create a
# very large executable, blender_add_test_lib() should be used instead.
function(blender_add_test_executable_impl
name
add_test_suite
sources
includes
includes_sys
library_deps
)
set(oneValueArgs ADD_CTESTS DISCOVER_TESTS)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
add_cc_flags_custom_test(${name} PARENT_SCOPE)
## Otherwise external projects will produce warnings that we cannot fix.
@ -220,19 +238,105 @@ function(blender_add_test_executable_impl
NAME ${name}
SRC "${sources}"
EXTRA_LIBS "${library_deps}"
SKIP_ADD_TEST
)
if(add_test_suite)
blender_add_test_suite(
if(ARGS_ADD_CTESTS)
blender_add_ctests(
TARGET ${name}_test
SUITE_NAME ${name}
SOURCES "${sources}"
DISCOVER_TESTS ${ARGS_DISCOVER_TESTS}
)
endif()
blender_target_include_dirs(${name}_test ${includes})
blender_target_include_dirs_sys(${name}_test ${includes_sys})
endfunction()
# Add tests for a Blender library, to be called in tandem with blender_add_lib().
#
# If WITH_TESTS_SINGLE_BINARY is enabled, this will generate a single executable
# named ${name}_test, and generate a separate ctest for every gtest contained in it.
#
# If WITH_TESTS_SINGLE_BINARY is disabled, this will generate an executable
# named ${name}_${source}_test for every source file (with redundant prefixes and
# postfixes stripped).
#
# To be used for smaller isolated libraries, that do not have many dependencies.
# For libraries that do drag in many other Blender libraries and would create a
# very large executable, blender_add_test_suite_lib() should be used instead.
#
# The function accepts an optional argument which denotes list of sources which
# is to be compiled-in with the suit sources for each fo the suites when the
# WITH_TESTS_SINGLE_BINARY configuration is set to OFF.
function(blender_add_test_suite_executable
name
sources
includes
includes_sys
library_deps
)
# Sources which are common for all suits and do not need to yield their own
# test suit binaries when WITH_TESTS_SINGLE_BINARY is OFF.
set(common_sources ${ARGN})
if(WITH_TESTS_SINGLE_BINARY)
blender_add_test_executable_impl(
"${name}"
"${sources};${common_sources}"
"${includes}"
"${includes_sys}"
"${library_deps}"
ADD_CTESTS TRUE
DISCOVER_TESTS TRUE
)
else()
foreach(source ${sources})
get_filename_component(_source_ext ${source} LAST_EXT)
if(NOT ${_source_ext} MATCHES "^\.h")
# Generate test name without redundant prefixes and postfixes.
get_filename_component(_test_name ${source} NAME_WE)
if(NOT ${_test_name} MATCHES "^${name}_")
set(_test_name "${name}_${_test_name}")
endif()
string(REGEX REPLACE "_test$" "" _test_name ${_test_name})
string(REGEX REPLACE "_tests$" "" _test_name ${_test_name})
blender_add_test_executable_impl(
"${_test_name}"
"${source};${common_sources}"
"${includes}"
"${includes_sys}"
"${library_deps}"
ADD_CTESTS TRUE
DISCOVER_TESTS FALSE
)
# Work-around run-time dynamic loader error
# symbol not found in flat namespace '_PyBaseObject_Type'
#
# Some tests are testing modules which are linked against Python, while some of unit
# tests might not use code path which uses Python functionality. In this case linker
# will optimize out all symbols from Python since it decides they are not used. This
# somehow conflicts with other libraries which are linked against the test binary and
# perform search of _PyBaseObject_Type on startup.
#
# Work-around by telling the linker that the python libraries should not be stripped.
if(APPLE)
target_link_libraries("${_test_name}_test" PRIVATE "-Wl,-force_load,${PYTHON_LIBRARIES}")
endif()
endif()
endforeach()
endif()
endfunction()
# Add test for a Blender library, to be called in tandem with blender_add_lib().
# Source files will be compiled into a single ${name}_test executable.
#
# To be used for smaller isolated libraries, that do not have many dependencies.
# For libraries that do drag in many other Blender libraries and would create a
# very large executable, blender_add_test_lib() should be used instead.
function(blender_add_test_executable
name
sources
@ -242,15 +346,18 @@ function(blender_add_test_executable
)
blender_add_test_executable_impl(
"${name}"
TRUE
"${sources}"
"${includes}"
"${includes_sys}"
"${library_deps}"
)
ADD_CTESTS TRUE
DISCOVER_TESTS FALSE
)
endfunction()
function(blender_add_performancetest_executable
# Add performance test. This is like blender_add_test_executable, but no ctest
# is generated and the binary should be run manually.
function(blender_add_test_performance_executable
name
sources
includes
@ -259,10 +366,12 @@ function(blender_add_performancetest_executable
)
blender_add_test_executable_impl(
"${name}"
FALSE
"${sources}"
"${includes}"
"${includes_sys}"
"${library_deps}"
ADD_CTESTS FALSE
DISCOVER_TESTS FALSE
)
endfunction()

@ -55,5 +55,5 @@ endif()
if(WITH_GTESTS AND WITH_CYCLES_LOGGING)
set(INC_SYS )
blender_add_test_executable(cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
blender_add_test_suite_executable(cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
endif()

@ -22,5 +22,5 @@ if(WITH_GTESTS)
if(WITH_IMAGE_OPENJPEG)
set(TEST_LIB ${TEST_LIB} ${OPENJPEG_LIBRARIES})
endif()
blender_add_test_lib(ffmpeg_codecs "${TEST_SRC}" "${TEST_INC}" "${TEST_INC_SYS}" "${TEST_LIB}")
blender_add_test_suite_lib(ffmpeg_codecs "${TEST_SRC}" "${TEST_INC}" "${TEST_INC_SYS}" "${TEST_LIB}")
endif()

@ -83,5 +83,5 @@ if(WITH_GTESTS)
bf_intern_guardedalloc
bf_blenlib
)
blender_add_test_executable(guardedalloc "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_executable(guardedalloc "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()

@ -108,5 +108,5 @@ if(WITH_GTESTS AND WITH_OPENSUBDIV)
add_definitions(${GFLAGS_DEFINES})
add_definitions(${GLOG_DEFINES})
blender_add_test_executable(opensubdiv_mesh_topology_test "internal/topology/mesh_topology_test.cc" "${INC}" "${INC_SYS}" "${LIB};bf_intern_opensubdiv")
blender_add_test_executable(opensubdiv_mesh_topology "internal/topology/mesh_topology_test.cc" "${INC}" "${INC_SYS}" "${LIB};bf_intern_opensubdiv")
endif()

@ -63,5 +63,5 @@ if(WITH_GTESTS)
set(TEST_LIB
PRIVATE bf::animrig
)
blender_add_test_lib(bf_animrig_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(animrig "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()

@ -58,11 +58,14 @@ if(WITH_GTESTS)
tests/asset_library_service_test.cc
tests/asset_library_test.cc
tests/asset_representation_test.cc
)
set(TEST_COMMON_SRC
tests/asset_library_test_common.hh
)
set(TEST_LIB
bf_asset_system
)
blender_add_test_lib(bf_asset_system_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(asset_system
"${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}" "${TEST_COMMON_SRC}"
)
endif()

@ -13,63 +13,6 @@
namespace blender::asset_system::tests {
static void compare_item_with_path(const AssetCatalogPath &expected_path,
const AssetCatalogTreeItem &actual_item)
{
if (expected_path != actual_item.catalog_path().str()) {
/* This will fail, but with a nicer error message than just calling FAIL(). */
EXPECT_EQ(expected_path, actual_item.catalog_path());
return;
}
/* Is the catalog name as expected? "character", "Ellie", ... */
EXPECT_EQ(expected_path.name(), actual_item.get_name());
/* Does the computed number of parents match? */
const std::string expected_path_str = expected_path.str();
const size_t expected_parent_count = std::count(
expected_path_str.begin(), expected_path_str.end(), AssetCatalogPath::SEPARATOR);
EXPECT_EQ(expected_parent_count, actual_item.count_parents());
}
void AssetCatalogTreeTestFunctions::expect_tree_items(
AssetCatalogTree *tree, const std::vector<AssetCatalogPath> &expected_paths)
{
int i = 0;
tree->foreach_item([&](const AssetCatalogTreeItem &actual_item) {
ASSERT_LT(i, expected_paths.size())
<< "More catalogs in tree than expected; did not expect " << actual_item.catalog_path();
compare_item_with_path(expected_paths[i], actual_item);
i++;
});
}
void AssetCatalogTreeTestFunctions::expect_tree_root_items(
AssetCatalogTree *tree, const std::vector<AssetCatalogPath> &expected_paths)
{
int i = 0;
tree->foreach_root_item([&](const AssetCatalogTreeItem &actual_item) {
ASSERT_LT(i, expected_paths.size())
<< "More catalogs in tree root than expected; did not expect "
<< actual_item.catalog_path();
compare_item_with_path(expected_paths[i], actual_item);
i++;
});
}
void AssetCatalogTreeTestFunctions::expect_tree_item_child_items(
AssetCatalogTreeItem *parent_item, const std::vector<AssetCatalogPath> &expected_paths)
{
int i = 0;
parent_item->foreach_child([&](const AssetCatalogTreeItem &actual_item) {
ASSERT_LT(i, expected_paths.size())
<< "More catalogs in tree item than expected; did not expect "
<< actual_item.catalog_path();
compare_item_with_path(expected_paths[i], actual_item);
i++;
});
}
class AssetCatalogTreeTest : public AssetLibraryTestBase, public AssetCatalogTreeTestFunctions {};
TEST_F(AssetCatalogTreeTest, insert_item_into_tree)

@ -7,6 +7,9 @@
#include <string>
#include <vector>
#include "AS_asset_catalog.hh"
#include "AS_asset_catalog_tree.hh"
#include "asset_library_service.hh"
#include "BKE_appdir.h"
@ -116,4 +119,61 @@ class AssetCatalogTreeTestFunctions {
const std::vector<AssetCatalogPath> &expected_paths);
};
static inline void compare_item_with_path(const AssetCatalogPath &expected_path,
const AssetCatalogTreeItem &actual_item)
{
if (expected_path != actual_item.catalog_path().str()) {
/* This will fail, but with a nicer error message than just calling FAIL(). */
EXPECT_EQ(expected_path, actual_item.catalog_path());
return;
}
/* Is the catalog name as expected? "character", "Ellie", ... */
EXPECT_EQ(expected_path.name(), actual_item.get_name());
/* Does the computed number of parents match? */
const std::string expected_path_str = expected_path.str();
const size_t expected_parent_count = std::count(
expected_path_str.begin(), expected_path_str.end(), AssetCatalogPath::SEPARATOR);
EXPECT_EQ(expected_parent_count, actual_item.count_parents());
}
inline void AssetCatalogTreeTestFunctions::expect_tree_items(
AssetCatalogTree *tree, const std::vector<AssetCatalogPath> &expected_paths)
{
int i = 0;
tree->foreach_item([&](const AssetCatalogTreeItem &actual_item) {
ASSERT_LT(i, expected_paths.size())
<< "More catalogs in tree than expected; did not expect " << actual_item.catalog_path();
compare_item_with_path(expected_paths[i], actual_item);
i++;
});
}
inline void AssetCatalogTreeTestFunctions::expect_tree_root_items(
AssetCatalogTree *tree, const std::vector<AssetCatalogPath> &expected_paths)
{
int i = 0;
tree->foreach_root_item([&](const AssetCatalogTreeItem &actual_item) {
ASSERT_LT(i, expected_paths.size())
<< "More catalogs in tree root than expected; did not expect "
<< actual_item.catalog_path();
compare_item_with_path(expected_paths[i], actual_item);
i++;
});
}
inline void AssetCatalogTreeTestFunctions::expect_tree_item_child_items(
AssetCatalogTreeItem *parent_item, const std::vector<AssetCatalogPath> &expected_paths)
{
int i = 0;
parent_item->foreach_child([&](const AssetCatalogTreeItem &actual_item) {
ASSERT_LT(i, expected_paths.size())
<< "More catalogs in tree item than expected; did not expect "
<< actual_item.catalog_path();
compare_item_with_path(expected_paths[i], actual_item);
i++;
});
}
} // namespace blender::asset_system::tests

@ -863,8 +863,9 @@ if(WITH_GTESTS)
set(TEST_INC
../editors/include
)
blender_add_test_lib(bf_blenkernel_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB}")
# RNA_prototypes.h
add_dependencies(bf_blenkernel_tests bf_rna)
set(TEST_LIB
${LIB}
bf_rna # RNA_prototypes.h
)
blender_add_test_suite_lib(blenkernel "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${TEST_LIB}")
endif()

@ -571,7 +571,7 @@ if(WITH_GTESTS)
set(TEST_LIB
bf_blenlib
)
blender_add_test_executable(blenlib "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_executable(BLI "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
add_subdirectory(tests/performance)
endif()

@ -18,4 +18,4 @@ set(LIB
PRIVATE bf::intern::atomic
)
blender_add_performancetest_executable(BLI_ghash_performance "BLI_ghash_performance_test.cc" "${INC}" "${INC_SYS}" "${LIB}")
blender_add_test_performance_executable(BLI_ghash_performance "BLI_ghash_performance_test.cc" "${INC}" "${INC_SYS}" "${LIB}")

@ -99,17 +99,36 @@ blender_add_lib(bf_blenloader "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
add_dependencies(bf_blenloader bf_rna)
if(WITH_GTESTS)
set(TEST_SRC
tests/blendfile_load_test.cc
# Utility functions for test also used by other tests.
set(TEST_UTIL_SRC
tests/blendfile_loading_base_test.cc
tests/blendfile_loading_base_test.h
)
set(TEST_INC
set(TEST_UTIL_INC
${INC}
../../../tests/gtests
../../../intern/ghost
)
set(TEST_LIB
set(TEST_UTIL_INC_SYS
${INC_SYS}
${GFLAGS_INCLUDE_DIRS}
${GLOG_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/extern/gtest/include
)
set(TEST_UTIL_LIB
${LIB}
bf_blenloader
)
blender_add_test_lib(bf_blenloader_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_lib(bf_blenloader_test_util "${TEST_UTIL_SRC}" "${TEST_UTIL_INC}" "${TEST_UTIL_INC_SYS}" "${TEST_UTIL_LIB}")
# Actual blenloader tests.
set(TEST_SRC
tests/blendfile_load_test.cc
)
set(TEST_LIB
${LIB}
bf_blenloader
bf_blenloader_test_util
)
blender_add_test_suite_lib(blenloader "${TEST_SRC}" "${INC}" "${INC_SYS}" "${TEST_LIB}")
endif()

@ -232,5 +232,5 @@ if(WITH_GTESTS)
set(TEST_LIB
bf_bmesh
)
blender_add_test_lib(bf_bmesh_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(bmesh "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()

@ -674,7 +674,7 @@ if(WITH_COMPOSITOR_CPU)
set(TEST_LIB
bf_compositor
)
blender_add_test_lib(bf_compositor_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(compositor "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()
# RNA_prototypes.h

@ -178,5 +178,5 @@ if(WITH_GTESTS)
set(TEST_LIB
bf_depsgraph
)
blender_add_test_lib(bf_depsgraph_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB}")
blender_add_test_suite_lib(depsgraph "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB}")
endif()

@ -995,6 +995,6 @@ if(WITH_GTESTS)
)
set(TEST_LIB
)
blender_add_test_lib(bf_draw_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(draw "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()
endif()

@ -71,5 +71,5 @@ if(WITH_GTESTS)
)
set(TEST_LIB
)
blender_add_test_lib(bf_editor_animation_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(editor_animation "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()

@ -79,5 +79,5 @@ if(WITH_GTESTS)
set(TEST_LIB
bf_functions
)
blender_add_test_lib(bf_functions_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(function "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()

@ -883,7 +883,11 @@ endif()
if(WITH_GTESTS)
set(TEST_SRC)
set(TEST_INC)
set(TEST_LIB)
set(TEST_LIB
bf_intern_ghost
bf_imbuf
bf_windowmanager
)
if(WITH_GPU_DRAW_TESTS)
list(APPEND TEST_SRC
@ -918,11 +922,13 @@ if(WITH_GTESTS)
endif()
if (TEST_SRC)
list(APPEND TEST_SRC
set(TEST_COMMON_SRC
tests/gpu_testing.cc
tests/gpu_testing.hh
)
blender_add_test_lib(bf_gpu_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(gpu
"${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}" "${TEST_COMMON_SRC}"
)
endif()
endif()

@ -114,5 +114,5 @@ if(WITH_GTESTS)
set(TEST_LIB
bf_io_alembic
)
blender_add_test_lib(bf_io_alembic_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(io_alembic "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()

@ -52,8 +52,8 @@ if(WITH_GTESTS)
../../blenloader
)
set(TEST_LIB
bf_blenloader_tests
bf_blenloader_test_util
bf_io_common
)
blender_add_test_lib(bf_io_common_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(io_common "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()

@ -73,6 +73,7 @@ if(WITH_GTESTS)
)
set(TEST_LIB
bf_io_ply
bf_blenloader_test_util
)
blender_add_test_lib(bf_io_ply_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(io_ply "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()

@ -67,10 +67,9 @@ if(WITH_GTESTS)
set(TEST_LIB
${LIB}
bf_blenloader_tests
bf_blenloader_test_util
bf_io_stl
)
blender_add_test_lib(bf_io_stl_tests "${TEST_SRC}" "${TEST_INC}" "${INC_SYS}" "${TEST_LIB}")
add_dependencies(bf_io_stl_tests bf_io_stl)
blender_add_test_suite_lib(io_stl "${TEST_SRC}" "${TEST_INC}" "${INC_SYS}" "${TEST_LIB}")
endif()

@ -252,8 +252,9 @@ if(WITH_GTESTS)
set(TEST_INC
)
set(TEST_LIB
bf_blenloader_test_util
)
blender_add_test_lib(bf_io_usd_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
blender_add_test_suite_lib(io_usd "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
endif()
# In CMAKE version 3.21 and up, we can instead use the `NO_CACHE` option for

@ -91,10 +91,9 @@ if(WITH_GTESTS)
set(TEST_LIB
${LIB}
bf_blenloader_tests
bf_blenloader_test_util
bf_io_wavefront_obj
)
blender_add_test_lib(bf_io_wavefront_obj_tests "${TEST_SRC}" "${TEST_INC}" "${INC_SYS}" "${TEST_LIB}")
add_dependencies(bf_io_wavefront_obj_tests bf_io_wavefront_obj)
blender_add_test_suite_lib(io_wavefront "${TEST_SRC}" "${TEST_INC}" "${INC_SYS}" "${TEST_LIB}")
endif()

@ -217,5 +217,5 @@ if(WITH_GTESTS)
set(TEST_SRC
intern/wm_dragdrop_test.cc
)
blender_add_test_lib(bf_wm_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB}")
blender_add_test_suite_lib(windowmanager "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB}")
endif()

@ -7,7 +7,9 @@ if(WITH_GTESTS)
remove_strict_flags()
# Build common test executable used by most tests
add_subdirectory(runner)
if(WITH_TESTS_SINGLE_BINARY)
add_subdirectory(runner)
endif()
# Build utility library used by test executables
add_subdirectory(testing)

@ -32,7 +32,6 @@ blender_src_gtest_ex(
NAME blender
SRC "${SRC}"
EXTRA_LIBS "${TEST_LIBS}"
SKIP_ADD_TEST
)
setup_platform_linker_libs(blender_test)

@ -702,7 +702,7 @@ if(WITH_CYCLES OR WITH_GPU_RENDER_TESTS)
# Eevee
foreach(render_test ${render_tests})
add_render_test(
eevee_${render_test}_test
eevee_${render_test}
${CMAKE_CURRENT_LIST_DIR}/eevee_render_tests.py
-testdir "${TEST_SRC_DIR}/render/${render_test}"
-outdir "${TEST_OUT_DIR}/eevee"
@ -712,7 +712,7 @@ if(WITH_CYCLES OR WITH_GPU_RENDER_TESTS)
# Eevee Next
foreach(render_test ${render_tests})
add_render_test(
eevee_next_${render_test}_test
eevee_next_${render_test}
${CMAKE_CURRENT_LIST_DIR}/eevee_next_render_tests.py
-testdir "${TEST_SRC_DIR}/render/${render_test}"
-outdir "${TEST_OUT_DIR}/eevee_next"
@ -722,7 +722,7 @@ if(WITH_CYCLES OR WITH_GPU_RENDER_TESTS)
foreach(render_test ${render_tests})
# Workbench
add_render_test(
workbench_${render_test}_test
workbench_${render_test}
${CMAKE_CURRENT_LIST_DIR}/workbench_render_tests.py
-testdir "${TEST_SRC_DIR}/render/${render_test}"
-outdir "${TEST_OUT_DIR}/workbench"
@ -733,7 +733,7 @@ if(WITH_CYCLES OR WITH_GPU_RENDER_TESTS)
# Hydra Storm
foreach(render_test ${render_tests})
add_render_test(
storm_hydra_${render_test}_test
storm_hydra_${render_test}
${CMAKE_CURRENT_LIST_DIR}/storm_render_tests.py
-testdir "${TEST_SRC_DIR}/render/${render_test}"
-outdir "${TEST_OUT_DIR}/storm_hydra"
@ -743,7 +743,7 @@ if(WITH_CYCLES OR WITH_GPU_RENDER_TESTS)
foreach(render_test ${render_tests})
add_render_test(
storm_usd_${render_test}_test
storm_usd_${render_test}
${CMAKE_CURRENT_LIST_DIR}/storm_render_tests.py
-testdir "${TEST_SRC_DIR}/render/${render_test}"
-outdir "${TEST_OUT_DIR}/storm_usd"
@ -776,7 +776,7 @@ if(WITH_COMPOSITOR_CPU)
foreach(comp_test ${compositor_tests})
add_render_test(
compositor_${comp_test}_cpu_test
compositor_${comp_test}_cpu
${CMAKE_CURRENT_LIST_DIR}/compositor_cpu_render_tests.py
-testdir "${TEST_SRC_DIR}/compositor/${comp_test}"
-outdir "${TEST_OUT_DIR}/compositor_cpu"
@ -808,7 +808,7 @@ if(WITH_COMPOSITOR_REALTIME_TESTS AND WITH_COMPOSITOR_CPU)
foreach(comp_test ${compositor_tests})
add_render_test(
compositor_${comp_test}_realtime_test
compositor_${comp_test}_realtime
${CMAKE_CURRENT_LIST_DIR}/compositor_realtime_render_tests.py
-testdir "${TEST_SRC_DIR}/compositor/${comp_test}"
-outdir "${TEST_OUT_DIR}/compositor_realtime"
@ -853,7 +853,7 @@ foreach(geo_node_test ${geo_node_tests})
foreach(file ${files})
get_filename_component(filename ${file} NAME_WE)
add_blender_test(
geo_node_${geo_node_test}_test_${filename}
geo_node_${geo_node_test}_${filename}
${file}
--python ${TEST_PYTHON_DIR}/geo_node_test.py
)
@ -915,7 +915,7 @@ if(WITH_ALEMBIC)
get_filename_component(ALEMBIC_ROOT_DIR ${real_include_dir} DIRECTORY)
add_python_test(
bf_io_alembic_export_tests
io_alembic_export_tests
${CMAKE_CURRENT_LIST_DIR}/alembic_export_tests.py
--blender "${TEST_BLENDER_EXE}"
--testdir "${TEST_SRC_DIR}/alembic"
@ -932,13 +932,13 @@ endif()
if(WITH_USD)
add_blender_test(
bf_io_usd_export_test
io_usd_export
--python ${CMAKE_CURRENT_LIST_DIR}/bl_usd_export_test.py
--
--testdir "${TEST_SRC_DIR}/usd"
)
add_blender_test(
bf_io_usd_import_test
io_usd_import
--python ${CMAKE_CURRENT_LIST_DIR}/bl_usd_import_test.py
--
--testdir "${TEST_SRC_DIR}/usd"
@ -972,7 +972,7 @@ else()
endif()
add_blender_test(
bf_imbuf_save
imbuf_save
--python ${CMAKE_CURRENT_LIST_DIR}/bl_imbuf_save.py
--
-test_dir "${TEST_SRC_DIR}/imbuf_io"
@ -982,7 +982,7 @@ else()
)
add_blender_test(
bf_imbuf_load
imbuf_load
--python ${CMAKE_CURRENT_LIST_DIR}/bl_imbuf_load.py
--
-test_dir "${TEST_SRC_DIR}/imbuf_io"
@ -1038,7 +1038,7 @@ if(WITH_UI_TESTS)
)
foreach(ui_test ${_undo_tests})
add_blender_test_headless(
"bf_ui_${ui_test}"
"ui_${ui_test}"
--enable-event-simulate
--python "${CMAKE_CURRENT_LIST_DIR}/ui_simulate/run_blender_setup.py"
--