diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index ae135e3899a..769496cce28 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -211,14 +211,23 @@ add_blender_test( --output-dir ${TEST_OUT_DIR}/blendfile_io/ ) -add_blender_test( - blendfile_versioning - --log "*blendfile*" - --debug-memory - --debug - --python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_versioning.py -- - --src-test-dir ${TEST_SRC_DIR}/ -) +# This test can be extremely long, especially in debug builds. +# Generate BLENDFILE_VERSIONING_SPLIT_RANGE instances of the test, +# each processing their own subset of the whole set of blendfiles. +set(BLENDFILE_VERSIONING_SPLIT_RANGE 8) +math(EXPR BLENDFILE_VERSIONING_SPLIT_RANGE_CMAKE "${BLENDFILE_VERSIONING_SPLIT_RANGE} - 1") +foreach(idx RANGE ${BLENDFILE_VERSIONING_SPLIT_RANGE_CMAKE}) + add_blender_test( + "blendfile_versioning_${idx}_over_${BLENDFILE_VERSIONING_SPLIT_RANGE}" + --log "*blendfile*" + --debug-memory + --debug + --python ${CMAKE_CURRENT_LIST_DIR}/bl_blendfile_versioning.py -- + --src-test-dir ${TEST_SRC_DIR}/ + --slice-range ${BLENDFILE_VERSIONING_SPLIT_RANGE} + --slice-index ${idx} + ) +endforeach() add_blender_test( blendfile_liblink diff --git a/tests/python/bl_blendfile_versioning.py b/tests/python/bl_blendfile_versioning.py index d47d3bc208e..c0b57c3ccfb 100644 --- a/tests/python/bl_blendfile_versioning.py +++ b/tests/python/bl_blendfile_versioning.py @@ -43,6 +43,14 @@ class TestBlendFileOpenAllTestFiles(TestHelper): "ram_glsl.blend", } + # Generate the slice of blendfile paths that this instance of the test should process. + blendfile_paths = [p for p in self.iter_blendfiles_from_directory(self.args.src_test_dir)] + # `os.scandir()` used by `iter_blendfiles_from_directory` does not + # guarantee any form of order. + blendfile_paths.sort() + slice_indices = self.generate_slice_indices(len(blendfile_paths), self.args.slice_range, self.args.slice_index) + self.blendfile_paths = blendfile_paths[slice_indices[0]:slice_indices[1]] + @classmethod def iter_blendfiles_from_directory(cls, root_path): for dir_entry in os.scandir(root_path): @@ -52,12 +60,20 @@ class TestBlendFileOpenAllTestFiles(TestHelper): if os.path.splitext(dir_entry.path)[1] == ".blend": yield dir_entry.path + @staticmethod + def generate_slice_indices(total_len, slice_range, slice_index): + slice_stride_base = total_len // slice_range + slice_stride_remain = total_len % slice_range + gen_indices = lambda i: ( + (i * (slice_stride_base + 1)) + if i < slice_stride_remain else + (slice_stride_remain * (slice_stride_base + 1)) + ((i - slice_stride_remain) * slice_stride_base) + ) + slice_indices = [(gen_indices(i), gen_indices(i + 1)) for i in range(slice_range)] + return slice_indices[slice_index] + def test_open(self): - blendfile_paths = [p for p in self.iter_blendfiles_from_directory(self.args.src_test_dir)] - # `os.scandir()` used by `iter_blendfiles_from_directory` does not - # guarantee any form of order. - blendfile_paths.sort() - for bfp in blendfile_paths: + for bfp in self.blendfile_paths: if os.path.basename(bfp) in self.excluded_paths: continue bpy.ops.wm.read_homefile(use_empty=True, use_factory_startup=True) @@ -84,12 +100,34 @@ def argparse_create(): required=False, ) + parser.add_argument( + "--slice-range", + dest="slice_range", + type=int, + default=1, + help="How many instances of this test are launched in parallel, the list of available blendfiles is then sliced " + "and each instance only processes the part matching its given `--slice-index`.", + required=False, + ) + parser.add_argument( + "--slice-index", + dest="slice_index", + type=int, + default=0, + help="The index of the slice in blendfiles that this instance should process." + "Should always be specified when `--slice-range` > 1", + required=False, + ) + return parser def main(): args = argparse_create().parse_args() + assert(args.slice_range > 0) + assert(0 <= args.slice_index < args.slice_range) + for Test in TESTS: Test(args).run_all_tests()