Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-08-21 12:35:51 +0300
committerJacques Lucke <jacques@blender.org>2020-08-21 12:49:57 +0300
commit3b93022e9213fce8b378bbc4d6ba229c2ddc849f (patch)
treee5aa9f544e84f1eb180c36d1208d36a8105cb16d
parent41d31e100d9d76aa8f20bd9fe8429122828dc7a9 (diff)
Tests: detect memory leaks in automated testsfail-on-memleak
A memory leak should be considered a bug. Therefore, it makes sense to fail tests when they contain memory leaks. Differential Revision: https://developer.blender.org/D8665
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h5
-rw-r--r--intern/guardedalloc/intern/leak_detector.cc19
-rw-r--r--source/creator/creator_args.c14
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/gtests/testing/testing_main.cc1
-rw-r--r--tests/python/collada/CMakeLists.txt6
-rw-r--r--tests/python/cycles_render_tests.py2
-rw-r--r--tests/python/eevee_render_tests.py2
-rwxr-xr-xtests/python/modules/test_utils.py2
-rw-r--r--tests/python/opengl_draw_tests.py2
-rw-r--r--tests/python/view_layer/CMakeLists.txt2
-rw-r--r--tests/python/workbench_render_tests.py2
12 files changed, 54 insertions, 5 deletions
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 9c62b2396f6..c05bda030ad 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -215,6 +215,11 @@ extern const char *(*MEM_name_ptr)(void *vmemh);
* about memory leaks will be printed on exit. */
void MEM_init_memleak_detection(void);
+/** When this has been called and memory leaks have been detected, the process will have an exit
+ * code that indicates failure. This can be used for when checking for memory leaks with automated
+ * tests. */
+void MEM_enable_fail_on_memleak(void);
+
/* Switch allocator to slower but fully guarded mode. */
void MEM_use_guarded_allocator(void);
diff --git a/intern/guardedalloc/intern/leak_detector.cc b/intern/guardedalloc/intern/leak_detector.cc
index d7b6f749742..bb816e7f2d3 100644
--- a/intern/guardedalloc/intern/leak_detector.cc
+++ b/intern/guardedalloc/intern/leak_detector.cc
@@ -18,6 +18,8 @@
* \ingroup MEM
*/
+#include <cstdlib>
+
#include "MEM_guardedalloc.h"
#include "mallocn_intern.h"
@@ -28,6 +30,9 @@ char free_after_leak_detection_message[] =
"error, use the 'construct on first use' idiom.";
namespace {
+
+static bool fail_on_memleak = false;
+
class MemLeakPrinter {
public:
~MemLeakPrinter()
@@ -42,6 +47,15 @@ class MemLeakPrinter {
leaked_blocks,
(double)mem_in_use / 1024 / 1024);
MEM_printmemlist();
+
+ if (fail_on_memleak) {
+ /* There are many other ways to change the exit code to failure here:
+ * - Make the destructor noexcept(false) and throw an exception.
+ * - Call exit(EXIT_FAILURE).
+ * - Call terminate().
+ */
+ abort();
+ }
}
};
} // namespace
@@ -59,3 +73,8 @@ void MEM_init_memleak_detection(void)
*/
static MemLeakPrinter printer;
}
+
+void MEM_enable_fail_on_memleak(void)
+{
+ fail_on_memleak = true;
+}
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index 164e670c444..cef1e75e04d 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -751,6 +751,18 @@ static int arg_handle_abort_handler_disable(int UNUSED(argc),
return 0;
}
+static const char arg_handle_fail_on_memleak_doc[] =
+ "\n\t"
+ "Exit with an exit code that indicates failure when memory leaks are detected.\n"
+ "This can be used to make automated tests fail.";
+static int arg_handle_fail_on_memleak(int UNUSED(argc),
+ const char **UNUSED(argv),
+ void *UNUSED(data))
+{
+ MEM_enable_fail_on_memleak();
+ return 0;
+}
+
static const char arg_handle_background_mode_set_doc[] =
"\n\t"
"Run in background (often used for UI-less rendering).";
@@ -2267,6 +2279,8 @@ void main_args_setup(bContext *C, bArgs *ba)
BLI_argsAdd(ba, 1, "-t", "--threads", CB(arg_handle_threads_set), NULL);
BLI_argsAdd(ba, 4, "-x", "--use-extension", CB(arg_handle_extension_set), C);
+ BLI_argsAdd(ba, 1, NULL, "--fail-on-memleak", CB(arg_handle_fail_on_memleak), NULL);
+
# undef CB
# undef CB_EX
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 0ee3b500fdf..73e318943d8 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -44,7 +44,7 @@ unset(_default_test_python_exe)
# Standard Blender arguments for running tests.
# Specify exit code so that if a Python script error happens, the test fails.
-set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --python-exit-code 1)
+set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --debug-memory --fail-on-memleak --python-exit-code 1)
# Python CTests
if(WITH_BLENDER AND WITH_PYTHON)
diff --git a/tests/gtests/testing/testing_main.cc b/tests/gtests/testing/testing_main.cc
index e9313b31909..6238101b319 100644
--- a/tests/gtests/testing/testing_main.cc
+++ b/tests/gtests/testing/testing_main.cc
@@ -50,6 +50,7 @@ int main(int argc, char **argv)
{
MEM_use_guarded_allocator();
MEM_init_memleak_detection();
+ MEM_enable_fail_on_memleak();
testing::InitGoogleTest(&argc, argv);
BLENDER_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
diff --git a/tests/python/collada/CMakeLists.txt b/tests/python/collada/CMakeLists.txt
index bf22de6b762..918599033a8 100644
--- a/tests/python/collada/CMakeLists.txt
+++ b/tests/python/collada/CMakeLists.txt
@@ -36,12 +36,12 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_OUT_DIR})
# all calls to blender use this
if(APPLE)
if(${CMAKE_GENERATOR} MATCHES "Xcode")
- set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup)
+ set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --debug-memory --fail-on-memleak)
else()
- set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
+ set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --debug-memory --fail-on-memleak --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
endif()
else()
- set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
+ set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --debug-memory --fail-on-memleak --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
endif()
# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py
index bdf4283eb3e..60453bc350e 100644
--- a/tests/python/cycles_render_tests.py
+++ b/tests/python/cycles_render_tests.py
@@ -20,6 +20,8 @@ def get_arguments(filepath, output_filepath):
"-noaudio",
"--factory-startup",
"--enable-autoexec",
+ "--debug-memory",
+ "--fail-on-memleak",
filepath,
"-E", "CYCLES",
"-o", output_filepath,
diff --git a/tests/python/eevee_render_tests.py b/tests/python/eevee_render_tests.py
index a7130136d0a..290768922be 100644
--- a/tests/python/eevee_render_tests.py
+++ b/tests/python/eevee_render_tests.py
@@ -103,6 +103,8 @@ def get_arguments(filepath, output_filepath):
"-noaudio",
"--factory-startup",
"--enable-autoexec",
+ "--debug-memory",
+ "--fail-on-memleak",
filepath,
"-E", "BLENDER_EEVEE",
"-P",
diff --git a/tests/python/modules/test_utils.py b/tests/python/modules/test_utils.py
index e31db05ba61..77fcdd184e3 100755
--- a/tests/python/modules/test_utils.py
+++ b/tests/python/modules/test_utils.py
@@ -79,6 +79,8 @@ class AbstractBlenderRunnerTest(unittest.TestCase):
'-noaudio',
'--factory-startup',
'--enable-autoexec',
+ '--debug-memory',
+ '--fail-on-memleak',
]
if blendfile:
diff --git a/tests/python/opengl_draw_tests.py b/tests/python/opengl_draw_tests.py
index ab4df63afd9..36cce29c92c 100644
--- a/tests/python/opengl_draw_tests.py
+++ b/tests/python/opengl_draw_tests.py
@@ -39,6 +39,8 @@ def get_arguments(filepath, output_filepath):
"-noaudio",
"--factory-startup",
"--enable-autoexec",
+ "--debug-memory",
+ "--fail-on-memleak",
filepath,
"-P",
os.path.realpath(__file__),
diff --git a/tests/python/view_layer/CMakeLists.txt b/tests/python/view_layer/CMakeLists.txt
index 3f38ee4675f..efcb15ba172 100644
--- a/tests/python/view_layer/CMakeLists.txt
+++ b/tests/python/view_layer/CMakeLists.txt
@@ -30,7 +30,7 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_OUT_DIR})
# endif()
# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
-set(TEST_BLENDER_EXE $<TARGET_FILE:blender> --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
+set(TEST_BLENDER_EXE $<TARGET_FILE:blender> --background -noaudio --factory-startup --debug-memory --fail-on-memleak --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
# ------------------------------------------------------------------------------
diff --git a/tests/python/workbench_render_tests.py b/tests/python/workbench_render_tests.py
index 155b54098a8..f1ea55165f4 100644
--- a/tests/python/workbench_render_tests.py
+++ b/tests/python/workbench_render_tests.py
@@ -39,6 +39,8 @@ def get_arguments(filepath, output_filepath):
"-noaudio",
"--factory-startup",
"--enable-autoexec",
+ "--debug-memory",
+ "--fail-on-memleak",
filepath,
"-E", "BLENDER_WORKBENCH",
"-P",