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:
Diffstat (limited to 'tests/python')
-rw-r--r--tests/python/CMakeLists.txt244
-rw-r--r--tests/python/batch_import.py6
-rw-r--r--tests/python/bl_alembic_import_test.py55
-rw-r--r--tests/python/bl_load_py_modules.py63
-rw-r--r--tests/python/bl_pyapi_bpy_utils_units.py19
-rw-r--r--tests/python/bl_run_operators.py6
-rwxr-xr-xtests/python/cycles_render_tests.py332
-rw-r--r--tests/python/render_layer/CMakeLists.txt2
-rw-r--r--tests/python/render_layer/render_layer_common.py9
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_a.py1
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_b.py1
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_c.py1
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_d.py1
-rw-r--r--tests/python/render_layer/test_evaluation_selectability_e.py1
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_a.py1
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_b.py1
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_c.py1
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_d.py1
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_e.py1
-rw-r--r--tests/python/render_layer/test_evaluation_visibility_f.py1
-rw-r--r--tests/python/render_layer/test_object_copy.py1
-rw-r--r--tests/python/render_layer/test_object_link_b.py1
-rw-r--r--tests/python/render_layer/test_operator_context.py4
-rw-r--r--tests/python/render_layer/test_scene_copy_d.py2
-rw-r--r--tests/python/render_layer/test_scene_copy_f.py94
-rw-r--r--tests/python/render_layer/test_scene_delete.py39
26 files changed, 703 insertions, 185 deletions
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index 20fa8257a32..a3460823e69 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -39,78 +39,101 @@ 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 ${EXECUTABLE_OUTPUT_PATH}/Debug/blender.app/Contents/MacOS/blender)
+ set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup)
else()
- set(TEST_BLENDER_EXE ${EXECUTABLE_OUTPUT_PATH}/blender.app/Contents/MacOS/blender)
+ set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
endif()
else()
- set(TEST_BLENDER_EXE ${EXECUTABLE_OUTPUT_PATH}/blender)
+ set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
endif()
# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
-set(TEST_BLENDER_EXE_BARE ${TEST_BLENDER_EXE})
-set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
-set(TEST_BLENDER_EXE ${TEST_BLENDER_EXE} ${TEST_BLENDER_EXE_PARAMS} )
+# set(TEST_BLENDER_EXE_BARE ${TEST_BLENDER_EXE})
+# set(TEST_BLENDER_EXE ${TEST_BLENDER_EXE} ${TEST_BLENDER_EXE_PARAMS} )
# ------------------------------------------------------------------------------
# GENERAL PYTHON CORRECTNESS TESTS
-add_test(script_load_keymap ${TEST_BLENDER_EXE}
+add_test(
+ NAME script_load_keymap
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_keymap_completeness.py
)
-add_test(script_load_addons ${TEST_BLENDER_EXE}
+add_test(
+ NAME script_load_addons
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_load_addons.py
)
-add_test(script_load_modules ${TEST_BLENDER_EXE}
+add_test(
+ NAME script_load_modules
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_load_py_modules.py
)
# test running operators doesn't segfault under various conditions
if(USE_EXPERIMENTAL_TESTS)
- add_test(script_run_operators ${TEST_BLENDER_EXE}
+ add_test(
+ NAME script_run_operators
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_run_operators.py
)
endif()
# ------------------------------------------------------------------------------
# PY API TESTS
-add_test(script_pyapi_bpy_path ${TEST_BLENDER_EXE}
+add_test(
+ NAME script_pyapi_bpy_path
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_path.py
)
-add_test(script_pyapi_bpy_utils_units ${TEST_BLENDER_EXE}
+add_test(
+ NAME script_pyapi_bpy_utils_units
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_utils_units.py
)
-add_test(script_pyapi_mathutils ${TEST_BLENDER_EXE}
+add_test(
+ NAME script_pyapi_mathutils
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_mathutils.py
)
-add_test(script_pyapi_idprop ${TEST_BLENDER_EXE}
+add_test(
+ NAME script_pyapi_idprop
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_idprop.py
)
-add_test(script_pyapi_idprop_datablock ${TEST_BLENDER_EXE}
+add_test(
+ NAME script_pyapi_idprop_datablock
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_idprop_datablock.py
)
# ------------------------------------------------------------------------------
# MODELING TESTS
-add_test(bevel ${TEST_BLENDER_EXE}
+add_test(
+ NAME bevel
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/modeling/bevel_regression.blend
--python-text run_tests
)
-add_test(split_faces ${TEST_BLENDER_EXE}
+add_test(
+ NAME split_faces
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/modeling/split_faces_test.blend
--python-text run_tests
)
# ------------------------------------------------------------------------------
# MODIFIERS TESTS
-add_test(modifier_array ${TEST_BLENDER_EXE}
+add_test(
+ NAME modifier_array
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/modifier_stack/array_test.blend
--python-text run_tests
)
@@ -121,21 +144,27 @@ add_test(modifier_array ${TEST_BLENDER_EXE}
# OBJ Import tests
# disabled until updated & working
if(FALSE)
-add_test(import_obj_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_obj_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.obj\(filepath='${TEST_SRC_DIR}/io_tests/obj/cube.obj'\)
--md5=39cce4bacac2d1b18fc470380279bc15 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_obj_cube.blend
)
-add_test(import_obj_nurbs_cyclic ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_obj_nurbs_cyclic
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.obj\(filepath='${TEST_SRC_DIR}/io_tests/obj/nurbs_cyclic.obj'\)
--md5=ad3c307e5883224a0492378cd32691ab --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_obj_nurbs_cyclic.blend
)
-add_test(import_obj_makehuman ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_obj_makehuman
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.obj\(filepath='${TEST_SRC_DIR}/io_tests/obj/makehuman.obj'\)
--md5=c9f78b185e58358daa4ecaecfa75464e --md5_method=SCENE
@@ -144,7 +173,9 @@ add_test(import_obj_makehuman ${TEST_BLENDER_EXE}
endif()
# OBJ Export tests
-add_test(export_obj_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_obj_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/all_quads.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.obj\(filepath='${TEST_OUT_DIR}/export_obj_cube.obj',use_selection=False\)
@@ -153,7 +184,9 @@ add_test(export_obj_cube ${TEST_BLENDER_EXE}
--md5=e80660437ad9bfe082849641c361a233 --md5_method=FILE
)
-add_test(export_obj_nurbs ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_obj_nurbs
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/nurbs.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.obj\(filepath='${TEST_OUT_DIR}/export_obj_nurbs.obj',use_selection=False,use_nurbs=True\)
@@ -164,7 +197,9 @@ add_test(export_obj_nurbs ${TEST_BLENDER_EXE}
# disabled until updated & working
if(FALSE)
-add_test(export_obj_all_objects ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_obj_all_objects
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_scene/all_objects.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.obj\(filepath='${TEST_OUT_DIR}/export_obj_all_objects.obj',use_selection=False,use_nurbs=True\)
@@ -177,21 +212,27 @@ endif()
# PLY Import tests
-add_test(import_ply_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_ply_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_mesh.ply\(filepath='${TEST_SRC_DIR}/io_tests/ply/cube_ascii.ply'\)
--md5=527134343c27fc0ea73115b85fbfd3ac --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_ply_cube.blend
)
-add_test(import_ply_bunny ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_ply_bunny
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_mesh.ply\(filepath='${TEST_SRC_DIR}/io_tests/ply/bunny2.ply'\)
--md5=6ea5b8533400a17accf928b8fd024eaa --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_ply_bunny.blend
)
-add_test(import_ply_small_holes ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_ply_small_holes
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_mesh.ply\(filepath='${TEST_SRC_DIR}/io_tests/ply/many_small_holes.ply'\)
--md5=c3093e26ecae5b6d59fbbcf2a0d0b39f --md5_method=SCENE
@@ -201,7 +242,9 @@ add_test(import_ply_small_holes ${TEST_BLENDER_EXE}
# PLY Export
# disabled until updated & working
if(FALSE)
-add_test(export_ply_cube_all_data ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_ply_cube_all_data
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/cube_all_data.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_mesh.ply\(filepath='${TEST_OUT_DIR}/export_ply_cube_all_data.ply'\)
@@ -209,7 +252,9 @@ add_test(export_ply_cube_all_data ${TEST_BLENDER_EXE}
--md5=6adc3748ceae8298496f99d0e7e76c15 --md5_method=FILE
)
-add_test(export_ply_suzanne_all_data ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_ply_suzanne_all_data
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/suzanne_all_data.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_mesh.ply\(filepath='${TEST_OUT_DIR}/export_ply_suzanne_all_data.ply'\)
@@ -218,7 +263,9 @@ add_test(export_ply_suzanne_all_data ${TEST_BLENDER_EXE}
)
endif()
-add_test(export_ply_vertices ${TEST_BLENDER_EXE} # lame, add a better one
+add_test(
+ NAME export_ply_vertices # lame, add a better one
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/vertices.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_mesh.ply\(filepath='${TEST_OUT_DIR}/export_ply_vertices.ply'\)
@@ -230,21 +277,27 @@ add_test(export_ply_vertices ${TEST_BLENDER_EXE} # lame, add a better one
# STL Import tests
# disabled until updated & working
if(FALSE)
-add_test(import_stl_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_stl_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_mesh.stl\(filepath='${TEST_SRC_DIR}/io_tests/stl/cube.stl'\)
--md5=8ceb5bb7e1cb5f4342fa1669988c66b4 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_stl_cube.blend
)
-add_test(import_stl_conrod ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_stl_conrod
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_mesh.stl\(filepath='${TEST_SRC_DIR}/io_tests/stl/conrod.stl'\)
--md5=690a4b8eb9002dcd8631c5a575ea7348 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_stl_conrod.blend
)
-add_test(import_stl_knot_max_simplified ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_stl_knot_max_simplified
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_mesh.stl\(filepath='${TEST_SRC_DIR}/io_tests/stl/knot_max_simplified.stl'\)
--md5=baf82803f45a84ec4ddbad9cef57dd3e --md5_method=SCENE
@@ -255,7 +308,9 @@ endif()
# STL Export
# disabled until updated & working
if(FALSE)
-add_test(export_stl_cube_all_data ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_stl_cube_all_data
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/cube_all_data.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_mesh.stl\(filepath='${TEST_OUT_DIR}/export_stl_cube_all_data.stl'\)
@@ -263,7 +318,9 @@ add_test(export_stl_cube_all_data ${TEST_BLENDER_EXE}
--md5=64cb97c0cabb015e1c3f76369835075a --md5_method=FILE
)
-add_test(export_stl_suzanne_all_data ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_stl_suzanne_all_data
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/suzanne_all_data.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_mesh.stl\(filepath='${TEST_OUT_DIR}/export_stl_suzanne_all_data.stl'\)
@@ -271,7 +328,9 @@ add_test(export_stl_suzanne_all_data ${TEST_BLENDER_EXE}
--md5=e9b23c97c139ad64961c635105bb9192 --md5_method=FILE
)
-add_test(export_stl_vertices ${TEST_BLENDER_EXE} # lame, add a better one
+add_test(
+ NAME export_stl_vertices # lame, add a better one
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/vertices.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_mesh.stl\(filepath='${TEST_OUT_DIR}/export_stl_vertices.stl'\)
@@ -284,21 +343,27 @@ endif()
# X3D Import
# disabled until updated & working
if(FALSE)
-add_test(import_x3d_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_x3d_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.x3d\(filepath='${TEST_SRC_DIR}/io_tests/x3d/color_cube.x3d'\)
--md5=3fae9be004199c145941cd3f9f80ad7b --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_x3d_cube.blend
)
-add_test(import_x3d_teapot ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_x3d_teapot
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.x3d\(filepath='${TEST_SRC_DIR}/io_tests/x3d/teapot.x3d'\)
--md5=8ee196c71947dce4199d55698501691e --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_x3d_teapot.blend
)
-add_test(import_x3d_suzanne_material ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_x3d_suzanne_material
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.x3d\(filepath='${TEST_SRC_DIR}/io_tests/x3d/suzanne_material.x3d'\)
--md5=3edea1353257d8b5a5f071942f417be6 --md5_method=SCENE
@@ -306,7 +371,9 @@ add_test(import_x3d_suzanne_material ${TEST_BLENDER_EXE}
)
# X3D Export
-add_test(export_x3d_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_x3d_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/all_quads.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_cube.x3d',use_selection=False\)
@@ -314,7 +381,9 @@ add_test(export_x3d_cube ${TEST_BLENDER_EXE}
--md5=05312d278fe41da33560fdfb9bdb268f --md5_method=FILE
)
-add_test(export_x3d_nurbs ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_x3d_nurbs
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/nurbs.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_nurbs.x3d',use_selection=False\)
@@ -322,7 +391,9 @@ add_test(export_x3d_nurbs ${TEST_BLENDER_EXE}
--md5=4286d4a2aa507ef78b22ddcbdcc88481 --md5_method=FILE
)
-add_test(export_x3d_all_objects ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_x3d_all_objects
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_scene/all_objects.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_all_objects.x3d',use_selection=False\)
@@ -336,21 +407,27 @@ endif()
# 3DS Import
# disabled until updated & working
if(FALSE)
-add_test(import_3ds_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_3ds_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.autodesk_3ds\(filepath='${TEST_SRC_DIR}/io_tests/3ds/cube.3ds'\)
--md5=cb5a45c35a343c3f5beca2a918472951 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_3ds_cube.blend
)
-add_test(import_3ds_hierarchy_lara ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_3ds_hierarchy_lara
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.autodesk_3ds\(filepath='${TEST_SRC_DIR}/io_tests/3ds/hierarchy_lara.3ds'\)
--md5=766c873d9fdb5f190e43796cfbae63b6 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_3ds_hierarchy_lara.blend
)
-add_test(import_3ds_hierarchy_greek_trireme ${TEST_BLENDER_EXE}
+add_test(
+ NAME import_3ds_hierarchy_greek_trireme
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.autodesk_3ds\(filepath='${TEST_SRC_DIR}/io_tests/3ds/hierarchy_greek_trireme.3ds'\)
--md5=b62ee30101e8999cb91ef4f8a8760056 --md5_method=SCENE
@@ -361,7 +438,9 @@ endif()
# 3DS Export
# disabled until updated & working
if(FALSE)
-add_test(export_3ds_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_3ds_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/all_quads.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.autodesk_3ds\(filepath='${TEST_OUT_DIR}/export_3ds_cube.3ds',use_selection=False\)
@@ -369,7 +448,9 @@ add_test(export_3ds_cube ${TEST_BLENDER_EXE}
--md5=a31f5071b6c6dc7445b9099cdc7f63b3 --md5_method=FILE
)
-add_test(export_3ds_nurbs ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_3ds_nurbs
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/nurbs.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.autodesk_3ds\(filepath='${TEST_OUT_DIR}/export_3ds_nurbs.3ds',use_selection=False\)
@@ -377,7 +458,9 @@ add_test(export_3ds_nurbs ${TEST_BLENDER_EXE}
--md5=5bdd21be3c80d814fbc83cb25edb08c2 --md5_method=FILE
)
-add_test(export_3ds_all_objects ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_3ds_all_objects
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_scene/all_objects.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.autodesk_3ds\(filepath='${TEST_OUT_DIR}/export_3ds_all_objects.3ds',use_selection=False\)
@@ -392,7 +475,9 @@ endif()
# 'use_metadata=False' for reliable md5's
# disabled until updated & working
if(FALSE)
-add_test(export_fbx_cube ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_fbx_cube
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/all_quads.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_cube.fbx',use_selection=False,use_metadata=False\)
@@ -400,7 +485,9 @@ add_test(export_fbx_cube ${TEST_BLENDER_EXE}
--md5=59a35577462f95f9a0b4e6035226ce9b --md5_method=FILE
)
-add_test(export_fbx_nurbs ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_fbx_nurbs
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_geometry/nurbs.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_nurbs.fbx',use_selection=False,use_metadata=False\)
@@ -408,7 +495,9 @@ add_test(export_fbx_nurbs ${TEST_BLENDER_EXE}
--md5=d31875f18f613fa0c3b16e978f87f6f8 --md5_method=FILE
)
-add_test(export_fbx_all_objects ${TEST_BLENDER_EXE}
+add_test(
+ NAME export_fbx_all_objects
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
${TEST_SRC_DIR}/io_tests/blend_scene/all_objects.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_all_objects.fbx',use_selection=False,use_metadata=False\)
@@ -421,31 +510,44 @@ if(WITH_CYCLES)
if(OPENIMAGEIO_IDIFF AND EXISTS "${TEST_SRC_DIR}/cycles/ctests/shader")
macro(add_cycles_render_test subject)
if(MSVC)
- add_test(NAME cycles_${subject}_test
+ add_test(
+ NAME cycles_${subject}_test
COMMAND
"$<TARGET_FILE_DIR:blender>/${BLENDER_VERSION_MAJOR}.${BLENDER_VERSION_MINOR}/python/bin/python$<$<CONFIG:Debug>:_d>"
${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
-blender "$<TARGET_FILE:blender>"
-testdir "${TEST_SRC_DIR}/cycles/ctests/${subject}"
-idiff "${OPENIMAGEIO_IDIFF}"
+ -outdir "${TEST_OUT_DIR}/cycles"
)
else()
- add_test(cycles_${subject}_test
- ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
- -blender "${TEST_BLENDER_EXE_BARE}"
+ add_test(
+ NAME cycles_${subject}_test
+ COMMAND ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
+ -blender "$<TARGET_FILE:blender>"
-testdir "${TEST_SRC_DIR}/cycles/ctests/${subject}"
-idiff "${OPENIMAGEIO_IDIFF}"
+ -outdir "${TEST_OUT_DIR}/cycles"
)
endif()
endmacro()
if(WITH_OPENGL_TESTS)
add_cycles_render_test(opengl)
endif()
- add_cycles_render_test(image)
+ add_cycles_render_test(bake)
+ add_cycles_render_test(denoise)
+ add_cycles_render_test(displacement)
+ add_cycles_render_test(image_data_types)
+ add_cycles_render_test(image_mapping)
+ add_cycles_render_test(image_texture_limit)
+ add_cycles_render_test(light)
add_cycles_render_test(mblur)
add_cycles_render_test(reports)
add_cycles_render_test(render)
add_cycles_render_test(shader)
+ add_cycles_render_test(shader_tangent)
+ add_cycles_render_test(shadow_catcher)
+ add_cycles_render_test(volume)
else()
MESSAGE(STATUS "Disabling Cycles tests because tests folder does not exist")
endif()
@@ -460,7 +562,9 @@ if(WITH_ALEMBIC)
get_filename_component(ALEMBIC_ROOT_DIR ${real_include_dir} DIRECTORY)
if(MSVC)
- add_test(NAME alembic_tests
+ # FIXME, de-duplicate.
+ add_test(
+ NAME alembic_tests
COMMAND
"$<TARGET_FILE_DIR:blender>/${BLENDER_VERSION_MAJOR}.${BLENDER_VERSION_MINOR}/python/bin/python$<$<CONFIG:Debug>:_d>"
${CMAKE_CURRENT_LIST_DIR}/alembic_tests.py
@@ -468,30 +572,24 @@ if(WITH_ALEMBIC)
--testdir "${TEST_SRC_DIR}/alembic"
--alembic-root "${ALEMBIC_ROOT_DIR}"
)
- add_test(NAME script_alembic_import
- COMMAND
- "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
- --python ${CMAKE_CURRENT_LIST_DIR}/bl_alembic_import_test.py
- --
- --testdir "${TEST_SRC_DIR}/alembic"
- --with-legacy-depsgraph=${WITH_LEGACY_DEPSGRAPH}
- )
-
else()
- add_test(alembic_tests
- ${CMAKE_CURRENT_LIST_DIR}/alembic_tests.py
- --blender "${TEST_BLENDER_EXE_BARE}"
+ add_test(
+ NAME alembic_tests
+ COMMAND ${CMAKE_CURRENT_LIST_DIR}/alembic_tests.py
+ --blender "$<TARGET_FILE:blender>"
--testdir "${TEST_SRC_DIR}/alembic"
--alembic-root "${ALEMBIC_ROOT_DIR}"
)
- add_test(script_alembic_import ${TEST_BLENDER_EXE}
+ endif()
+
+ add_test(
+ NAME script_alembic_import
+ COMMAND "$<TARGET_FILE:blender>" ${TEST_BLENDER_EXE_PARAMS}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_alembic_import_test.py
--
--testdir "${TEST_SRC_DIR}/alembic"
--with-legacy-depsgraph=${WITH_LEGACY_DEPSGRAPH}
- )
-
- endif()
+ )
endif()
add_subdirectory(render_layer)
diff --git a/tests/python/batch_import.py b/tests/python/batch_import.py
index bbe3a70327f..a6e2469349b 100644
--- a/tests/python/batch_import.py
+++ b/tests/python/batch_import.py
@@ -72,10 +72,8 @@ def batch_import(
def file_generator(path):
for dirpath, dirnames, filenames in os.walk(path):
-
- # skip '.svn'
- if dirpath.startswith("."):
- continue
+ # skip '.git'
+ dirnames[:] = [d for d in dirnames if not d.startswith(".")]
for filename in filenames:
if pattern_match(filename):
diff --git a/tests/python/bl_alembic_import_test.py b/tests/python/bl_alembic_import_test.py
index 2f3daaefd44..e64da2fe540 100644
--- a/tests/python/bl_alembic_import_test.py
+++ b/tests/python/bl_alembic_import_test.py
@@ -75,6 +75,39 @@ class SimpleImportTest(AbstractAlembicTest):
self.assertEqual(objects['Cube_003'], objects['Cube_005'].parent)
self.assertEqual(objects['Cube_003'], objects['Cube_006'].parent)
+ def test_inherit_or_not(self):
+ res = bpy.ops.wm.alembic_import(
+ filepath=str(self.testdir / "T52022-inheritance.abc"),
+ as_background_job=False)
+ self.assertEqual({'FINISHED'}, res)
+
+ # The objects should be linked to scene_collection in Blender 2.8,
+ # and to scene in Blender 2.7x.
+ objects = bpy.context.scene_collection.objects
+
+ # ABC parent is top-level object, which translates to nothing in Blender
+ self.assertIsNone(objects['locator1'].parent)
+
+ # ABC parent is locator1, but locator2 has "inherits Xforms" = false, which
+ # translates to "no parent" in Blender.
+ self.assertIsNone(objects['locator2'].parent)
+
+ # Shouldn't have inherited the ABC parent's transform.
+ x, y, z = objects['locator2'].matrix_world.to_translation()
+ self.assertAlmostEqual(0, x)
+ self.assertAlmostEqual(0, y)
+ self.assertAlmostEqual(2, z)
+
+ # ABC parent is inherited and translates to normal parent in Blender.
+ self.assertEqual(objects['locator2'], objects['locatorShape2'].parent)
+
+ # Should have inherited its ABC parent's transform.
+ x, y, z = objects['locatorShape2'].matrix_world.to_translation()
+ self.assertAlmostEqual(0, x)
+ self.assertAlmostEqual(0, y)
+ self.assertAlmostEqual(2, z)
+
+
def test_select_after_import(self):
# Add a sphere, so that there is something in the scene, selected, and active,
# before we do the Alembic import.
@@ -146,22 +179,26 @@ class SimpleImportTest(AbstractAlembicTest):
res = bpy.ops.wm.alembic_import(filepath=str(abc), as_background_job=False)
self.assertEqual({'FINISHED'}, res)
- cube = bpy.context.active_object
+ plane = bpy.context.active_object
# Check that the file loaded ok.
bpy.context.scene.frame_set(6)
- self.assertAlmostEqual(-1, cube.data.vertices[0].co.x)
- self.assertAlmostEqual(-1, cube.data.vertices[0].co.y)
- self.assertAlmostEqual(0.5905638933181763, cube.data.vertices[0].co.z)
+ scene = bpy.context.scene
+ layer = scene.render_layers[scene.active_layer]
+ mesh = plane.to_mesh(scene, layer, True, 'RENDER')
+ self.assertAlmostEqual(-1, mesh.vertices[0].co.x)
+ self.assertAlmostEqual(-1, mesh.vertices[0].co.y)
+ self.assertAlmostEqual(0.5905638933181763, mesh.vertices[0].co.z)
# Change path from absolute to relative. This should not break the animation.
- bpy.context.scene.frame_set(1)
+ scene.frame_set(1)
bpy.data.cache_files[fname].filepath = relpath
- bpy.context.scene.frame_set(6)
+ scene.frame_set(6)
- self.assertAlmostEqual(1, cube.data.vertices[3].co.x)
- self.assertAlmostEqual(1, cube.data.vertices[3].co.y)
- self.assertAlmostEqual(0.5905638933181763, cube.data.vertices[3].co.z)
+ mesh = plane.to_mesh(scene, layer, True, 'RENDER')
+ self.assertAlmostEqual(1, mesh.vertices[3].co.x)
+ self.assertAlmostEqual(1, mesh.vertices[3].co.y)
+ self.assertAlmostEqual(0.5905638933181763, mesh.vertices[3].co.z)
def test_import_long_names(self):
# This file contains very long names. The longest name is 4047 chars.
diff --git a/tests/python/bl_load_py_modules.py b/tests/python/bl_load_py_modules.py
index 4935491a6be..39e7bd33d44 100644
--- a/tests/python/bl_load_py_modules.py
+++ b/tests/python/bl_load_py_modules.py
@@ -38,7 +38,7 @@ BLACKLIST = {
'io_import_dxf', # Because of cydxfentity.so dependency
# The unpacked wheel is only loaded when actually used, not directly on import:
- "io_blend_utils/blender_bam-unpacked.whl",
+ os.path.join("io_blend_utils", "blender_bam-unpacked.whl"),
}
# Some modules need to add to the `sys.path`.
@@ -93,9 +93,8 @@ def addon_modules_sorted():
def source_list(path, filename_check=None):
from os.path import join
for dirpath, dirnames, filenames in os.walk(path):
- # skip '.svn'
- if dirpath.startswith("."):
- continue
+ # skip '.git'
+ dirnames[:] = [d for d in dirnames if not d.startswith(".")]
for filename in filenames:
filepath = join(dirpath, filename)
@@ -123,6 +122,8 @@ def load_addons():
def load_modules():
+ VERBOSE = os.environ.get("BLENDER_VERBOSE") is not None
+
modules = []
module_paths = []
@@ -162,6 +163,14 @@ def load_modules():
del module_names
#
+ # test we tested all files except for presets and templates
+ ignore_paths = [
+ os.sep + "presets" + os.sep,
+ os.sep + "templates" + os.sep,
+ ] + ([(os.sep + f + os.sep) for f in BLACKLIST] +
+ [(os.sep + f + ".py") for f in BLACKLIST])
+
+ #
# now submodules
for m in modules:
filepath = m.__file__
@@ -178,15 +187,35 @@ def load_modules():
for f in MODULE_SYS_PATHS.get(mod_name_full, ())
])
- __import__(mod_name_full)
- mod_imp = sys.modules[mod_name_full]
-
- sys.path[:] = sys_path_back
-
- # check we load what we ask for.
- assert(os.path.samefile(mod_imp.__file__, submod_full))
-
- modules.append(mod_imp)
+ try:
+ __import__(mod_name_full)
+ mod_imp = sys.modules[mod_name_full]
+
+ sys.path[:] = sys_path_back
+
+ # check we load what we ask for.
+ assert(os.path.samefile(mod_imp.__file__, submod_full))
+
+ modules.append(mod_imp)
+ except Exception as e:
+ import traceback
+ # Module might fail to import, but we don't want whole test to fail here.
+ # Reasoning:
+ # - This module might be in ignored list (for example, preset or template),
+ # so failing here will cause false-positive test failure.
+ # - If this is module which should not be ignored, it is not added to list
+ # of successfully loaded modules, meaning the test will catch this
+ # import failure.
+ # - We want to catch all failures of this script instead of stopping on
+ # a first big failure.
+ do_print = True
+ if not VERBOSE:
+ for ignore in ignore_paths:
+ if ignore in submod_full:
+ do_print = False
+ break
+ if do_print:
+ traceback.print_exc()
#
# check which filepaths we didn't load
@@ -205,14 +234,6 @@ def load_modules():
for f in loaded_files:
source_files.remove(f)
- #
- # test we tested all files except for presets and templates
- ignore_paths = [
- os.sep + "presets" + os.sep,
- os.sep + "templates" + os.sep,
- ] + ([(os.sep + f + os.sep) for f in BLACKLIST] +
- [(os.sep + f + ".py") for f in BLACKLIST])
-
for f in source_files:
for ignore in ignore_paths:
if ignore in f:
diff --git a/tests/python/bl_pyapi_bpy_utils_units.py b/tests/python/bl_pyapi_bpy_utils_units.py
index f40dab4b5eb..251419cb9ef 100644
--- a/tests/python/bl_pyapi_bpy_utils_units.py
+++ b/tests/python/bl_pyapi_bpy_utils_units.py
@@ -32,18 +32,17 @@ class UnitsTesting(unittest.TestCase):
OUTPUT_TESTS = (
# system, type, prec, sep, compat, value, output
##### LENGTH
+ # Note: precision handling is a bit complicated when using multi-units...
('IMPERIAL', 'LENGTH', 3, False, False, 0.3048, "1'"),
('IMPERIAL', 'LENGTH', 3, False, True, 0.3048, "1ft"),
- ('IMPERIAL', 'LENGTH', 3, True, False, 0.3048 * 2 + 0.0254 * 5.5, "2' 5.5\""),
- # Those next two fail, here again because precision ignores order magnitude :/
- #('IMPERIAL', 'LENGTH', 3, False, False, 1609.344 * 1e6, "1000000mi"), # == 1000000.004mi!!!
- #('IMPERIAL', 'LENGTH', 6, False, False, 1609.344 * 1e6, "1000000mi"), # == 1000000.003641mi!!!
- ('METRIC', 'LENGTH', 3, True, False, 1000 * 2 + 0.001 * 15, "2km 1.5cm"),
- ('METRIC', 'LENGTH', 3, True, False, 1234.56789, "1km 234.6m"),
- # Note: precision seems basically unused when using multi units!
- ('METRIC', 'LENGTH', 9, True, False, 1234.56789, "1km 234.6m"),
- ('METRIC', 'LENGTH', 9, False, False, 1234.56789, "1.23456789km"),
- ('METRIC', 'LENGTH', 9, True, False, 1000.000123456789, "1km 0.1mm"),
+ ('IMPERIAL', 'LENGTH', 4, True, False, 0.3048 * 2 + 0.0254 * 5.5, "2' 5.5\""),
+ ('IMPERIAL', 'LENGTH', 3, False, False, 1609.344 * 1e6, "1000000mi"),
+ ('IMPERIAL', 'LENGTH', 6, False, False, 1609.344 * 1e6, "1000000mi"),
+ ('METRIC', 'LENGTH', 3, True, False, 1000 * 2 + 0.001 * 15, "2km 2cm"),
+ ('METRIC', 'LENGTH', 5, True, False, 1234.56789, "1km 234.6m"),
+ ('METRIC', 'LENGTH', 6, True, False, 1234.56789, "1km 234.57m"),
+ ('METRIC', 'LENGTH', 9, False, False, 1234.56789, "1.234568km"),
+ ('METRIC', 'LENGTH', 9, True, False, 1000.000123456789, "1km 0.123mm"),
)
def test_units_inputs(self):
diff --git a/tests/python/bl_run_operators.py b/tests/python/bl_run_operators.py
index 7d5f4127378..7b6b97e5ad1 100644
--- a/tests/python/bl_run_operators.py
+++ b/tests/python/bl_run_operators.py
@@ -100,10 +100,8 @@ def blend_list(mainpath):
def file_list(path, filename_check=None):
for dirpath, dirnames, filenames in os.walk(path):
-
- # skip '.svn'
- if dirpath.startswith("."):
- continue
+ # skip '.git'
+ dirnames[:] = [d for d in dirnames if not d.startswith(".")]
for filename in filenames:
filepath = join(dirpath, filename)
diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py
index a030cc5e0de..2122150467c 100755
--- a/tests/python/cycles_render_tests.py
+++ b/tests/python/cycles_render_tests.py
@@ -2,7 +2,10 @@
# Apache License, Version 2.0
import argparse
+import glob
import os
+import pathlib
+import shlex
import shutil
import subprocess
import sys
@@ -24,7 +27,7 @@ class COLORS_DUMMY:
COLORS = COLORS_DUMMY
-def printMessage(type, status, message):
+def print_message(message, type=None, status=''):
if type == 'SUCCESS':
print(COLORS.GREEN, end="")
elif type == 'FAILURE':
@@ -50,38 +53,60 @@ def render_file(filepath):
dirname = os.path.dirname(filepath)
basedir = os.path.dirname(dirname)
subject = os.path.basename(dirname)
+
+ custom_args = os.getenv('CYCLESTEST_ARGS')
+ custom_args = shlex.split(custom_args) if custom_args else []
+
+ # OSL and GPU examples
+ # custom_args += ["--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True"]
+ # custom_args += ["--python-expr", "import bpy; bpy.context.scene.cycles.device = 'GPU'"]
+
if subject == 'opengl':
- command = (
+ command = [
BLENDER,
"--window-geometry", "0", "0", "1", "1",
"-noaudio",
"--factory-startup",
"--enable-autoexec",
filepath,
- "-E", "CYCLES",
- # Run with OSL enabled
- # "--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True",
+ "-E", "CYCLES"]
+ command += custom_args
+ command += [
"-o", TEMP_FILE_MASK,
"-F", "PNG",
'--python', os.path.join(basedir,
"util",
- "render_opengl.py")
- )
+ "render_opengl.py")]
+ elif subject == 'bake':
+ command = [
+ BLENDER,
+ "-b",
+ "-noaudio",
+ "--factory-startup",
+ "--enable-autoexec",
+ filepath,
+ "-E", "CYCLES"]
+ command += custom_args
+ command += [
+ "-o", TEMP_FILE_MASK,
+ "-F", "PNG",
+ '--python', os.path.join(basedir,
+ "util",
+ "render_bake.py")]
else:
- command = (
+ command = [
BLENDER,
"--background",
"-noaudio",
"--factory-startup",
"--enable-autoexec",
filepath,
- "-E", "CYCLES",
- # Run with OSL enabled
- # "--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True",
+ "-E", "CYCLES"]
+ command += custom_args
+ command += [
"-o", TEMP_FILE_MASK,
"-F", "PNG",
- "-f", "1",
- )
+ "-f", "1"]
try:
output = subprocess.check_output(command)
if VERBOSE:
@@ -109,68 +134,241 @@ def test_get_name(filepath):
filename = os.path.basename(filepath)
return os.path.splitext(filename)[0]
-
-def verify_output(filepath):
+def test_get_images(filepath):
testname = test_get_name(filepath)
dirpath = os.path.dirname(filepath)
- reference_dirpath = os.path.join(dirpath, "reference_renders")
- reference_image = os.path.join(reference_dirpath, testname + ".png")
- failed_image = os.path.join(reference_dirpath, testname + ".fail.png")
- if not os.path.exists(reference_image):
- return False
+
+ old_dirpath = os.path.join(dirpath, "reference_renders")
+ old_img = os.path.join(old_dirpath, testname + ".png")
+
+ ref_dirpath = os.path.join(OUTDIR, os.path.basename(dirpath), "ref")
+ ref_img = os.path.join(ref_dirpath, testname + ".png")
+ if not os.path.exists(ref_dirpath):
+ os.makedirs(ref_dirpath)
+ if os.path.exists(old_img):
+ shutil.copy(old_img, ref_img)
+
+ new_dirpath = os.path.join(OUTDIR, os.path.basename(dirpath))
+ if not os.path.exists(new_dirpath):
+ os.makedirs(new_dirpath)
+ new_img = os.path.join(new_dirpath, testname + ".png")
+
+ diff_dirpath = os.path.join(OUTDIR, os.path.basename(dirpath), "diff")
+ if not os.path.exists(diff_dirpath):
+ os.makedirs(diff_dirpath)
+ diff_img = os.path.join(diff_dirpath, testname + ".diff.png")
+
+ return old_img, ref_img, new_img, diff_img
+
+
+class Report:
+ def __init__(self, testname):
+ self.failed_tests = ""
+ self.passed_tests = ""
+ self.testname = testname
+
+ def output(self):
+ # write intermediate data for single test
+ outdir = os.path.join(OUTDIR, self.testname)
+ if not os.path.exists(outdir):
+ os.makedirs(outdir)
+
+ filepath = os.path.join(outdir, "failed.data")
+ pathlib.Path(filepath).write_text(self.failed_tests)
+
+ filepath = os.path.join(outdir, "passed.data")
+ pathlib.Path(filepath).write_text(self.passed_tests)
+
+ # gather intermediate data for all tests
+ failed_data = sorted(glob.glob(os.path.join(OUTDIR, "*/failed.data")))
+ passed_data = sorted(glob.glob(os.path.join(OUTDIR, "*/passed.data")))
+
+ failed_tests = ""
+ passed_tests = ""
+
+ for filename in failed_data:
+ filepath = os.path.join(OUTDIR, filename)
+ failed_tests += pathlib.Path(filepath).read_text()
+ for filename in passed_data:
+ filepath = os.path.join(OUTDIR, filename)
+ passed_tests += pathlib.Path(filepath).read_text()
+
+ # write html for all tests
+ self.html = """
+<html>
+<head>
+ <title>Cycles Test Report</title>
+ <style>
+ img {{ image-rendering: pixelated; width: 256px; background-color: #000; }}
+ img.render {{
+ background-color: #fff;
+ background-image:
+ -moz-linear-gradient(45deg, #eee 25%, transparent 25%),
+ -moz-linear-gradient(-45deg, #eee 25%, transparent 25%),
+ -moz-linear-gradient(45deg, transparent 75%, #eee 75%),
+ -moz-linear-gradient(-45deg, transparent 75%, #eee 75%);
+ background-image:
+ -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, #eee), color-stop(.25, transparent)),
+ -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, #eee), color-stop(.25, transparent)),
+ -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, #eee)),
+ -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #eee));
+
+ -moz-background-size:50px 50px;
+ background-size:50px 50px;
+ -webkit-background-size:50px 51px; /* override value for shitty webkit */
+
+ background-position:0 0, 25px 0, 25px -25px, 0px 25px;
+ }}
+ table td:first-child {{ width: 256px; }}
+ </style>
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
+</head>
+<body>
+ <div class="container">
+ <br/>
+ <h1>Cycles Test Report</h1>
+ <br/>
+ <table class="table table-striped">
+ <thead class="thead-default">
+ <tr><th>Name</th><th>New</th><th>Reference</th><th>Diff</th>
+ </thead>
+ {}{}
+ </table>
+ <br/>
+ </div>
+</body>
+</html>
+ """ . format(failed_tests, passed_tests)
+
+ filepath = os.path.join(OUTDIR, "report.html")
+ pathlib.Path(filepath).write_text(self.html)
+
+ print_message("Report saved to: " + pathlib.Path(filepath).as_uri())
+
+ def relative_url(self, filepath):
+ relpath = os.path.relpath(filepath, OUTDIR)
+ return pathlib.Path(relpath).as_posix()
+
+ def add_test(self, filepath, error):
+ name = test_get_name(filepath)
+ name = name.replace('_', ' ')
+
+ old_img, ref_img, new_img, diff_img = test_get_images(filepath)
+
+ status = error if error else ""
+ style = """ style="background-color: #f99;" """ if error else ""
+
+ new_url = self.relative_url(new_img)
+ ref_url = self.relative_url(ref_img)
+ diff_url = self.relative_url(diff_img)
+
+ test_html = """
+ <tr{}>
+ <td><b>{}</b><br/>{}<br/>{}</td>
+ <td><img src="{}" onmouseover="this.src='{}';" onmouseout="this.src='{}';" class="render"></td>
+ <td><img src="{}" onmouseover="this.src='{}';" onmouseout="this.src='{}';" class="render"></td>
+ <td><img src="{}"></td>
+ </tr>""" . format(style, name, self.testname, status,
+ new_url, ref_url, new_url,
+ ref_url, new_url, ref_url,
+ diff_url)
+
+ if error:
+ self.failed_tests += test_html
+ else:
+ self.passed_tests += test_html
+
+
+def verify_output(report, filepath):
+ old_img, ref_img, new_img, diff_img = test_get_images(filepath)
+
+ # copy new image
+ if os.path.exists(new_img):
+ os.remove(new_img)
+ if os.path.exists(TEMP_FILE):
+ shutil.copy(TEMP_FILE, new_img)
+
+ update = os.getenv('CYCLESTEST_UPDATE')
+
+ if os.path.exists(ref_img):
+ # diff test with threshold
+ command = (
+ IDIFF,
+ "-fail", "0.016",
+ "-failpercent", "1",
+ ref_img,
+ TEMP_FILE,
+ )
+ try:
+ subprocess.check_output(command)
+ failed = False
+ except subprocess.CalledProcessError as e:
+ if VERBOSE:
+ print_message(e.output.decode("utf-8"))
+ failed = e.returncode != 1
+ else:
+ if not update:
+ return False
+
+ failed = True
+
+ if failed and update:
+ # update reference
+ shutil.copy(new_img, ref_img)
+ shutil.copy(new_img, old_img)
+ failed = False
+
+ # generate diff image
command = (
IDIFF,
- "-fail", "0.015",
- "-failpercent", "1",
- reference_image,
- TEMP_FILE,
+ "-o", diff_img,
+ "-abs", "-scale", "16",
+ ref_img,
+ TEMP_FILE
)
+
try:
subprocess.check_output(command)
- failed = False
except subprocess.CalledProcessError as e:
if VERBOSE:
- print(e.output.decode("utf-8"))
- failed = e.returncode != 1
- if failed:
- shutil.copy(TEMP_FILE, failed_image)
- elif os.path.exists(failed_image):
- os.remove(failed_image)
+ print_message(e.output.decode("utf-8"))
+
return not failed
-def run_test(filepath):
+def run_test(report, filepath):
testname = test_get_name(filepath)
spacer = "." * (32 - len(testname))
- printMessage('SUCCESS', 'RUN', testname)
+ print_message(testname, 'SUCCESS', 'RUN')
time_start = time.time()
error = render_file(filepath)
status = "FAIL"
if not error:
- if not verify_output(filepath):
+ if not verify_output(report, filepath):
error = "VERIFY"
time_end = time.time()
elapsed_ms = int((time_end - time_start) * 1000)
if not error:
- printMessage('SUCCESS', 'OK', "{} ({} ms)" .
- format(testname, elapsed_ms))
+ print_message("{} ({} ms)" . format(testname, elapsed_ms),
+ 'SUCCESS', 'OK')
else:
if error == "NO_CYCLES":
- print("Can't perform tests because Cycles failed to load!")
- return False
+ print_message("Can't perform tests because Cycles failed to load!")
+ return error
elif error == "NO_START":
- print('Can not perform tests because blender fails to start.',
+ print_message('Can not perform tests because blender fails to start.',
'Make sure INSTALL target was run.')
- return False
+ return error
elif error == 'VERIFY':
- print("Rendered result is different from reference image")
+ print_message("Rendered result is different from reference image")
else:
- print("Unknown error %r" % error)
- printMessage('FAILURE', 'FAILED', "{} ({} ms)" .
- format(testname, elapsed_ms))
+ print_message("Unknown error %r" % error)
+ print_message("{} ({} ms)" . format(testname, elapsed_ms),
+ 'FAILURE', 'FAILED')
return error
+
def blend_list(path):
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
@@ -178,17 +376,18 @@ def blend_list(path):
filepath = os.path.join(dirpath, filename)
yield filepath
-
def run_all_tests(dirpath):
passed_tests = []
failed_tests = []
all_files = list(blend_list(dirpath))
all_files.sort()
- printMessage('SUCCESS', "==========",
- "Running {} tests from 1 test case." . format(len(all_files)))
+ report = Report(os.path.basename(dirpath))
+ print_message("Running {} tests from 1 test case." .
+ format(len(all_files)),
+ 'SUCCESS', "==========")
time_start = time.time()
for filepath in all_files:
- error = run_test(filepath)
+ error = run_test(report, filepath)
testname = test_get_name(filepath)
if error:
if error == "NO_CYCLES":
@@ -198,28 +397,33 @@ def run_all_tests(dirpath):
failed_tests.append(testname)
else:
passed_tests.append(testname)
+ report.add_test(filepath, error)
time_end = time.time()
elapsed_ms = int((time_end - time_start) * 1000)
- print("")
- printMessage('SUCCESS', "==========",
- "{} tests from 1 test case ran. ({} ms total)" .
- format(len(all_files), elapsed_ms))
- printMessage('SUCCESS', 'PASSED', "{} tests." .
- format(len(passed_tests)))
+ print_message("")
+ print_message("{} tests from 1 test case ran. ({} ms total)" .
+ format(len(all_files), elapsed_ms),
+ 'SUCCESS', "==========")
+ print_message("{} tests." .
+ format(len(passed_tests)),
+ 'SUCCESS', 'PASSED')
if failed_tests:
- printMessage('FAILURE', 'FAILED', "{} tests, listed below:" .
- format(len(failed_tests)))
+ print_message("{} tests, listed below:" .
+ format(len(failed_tests)),
+ 'FAILURE', 'FAILED')
failed_tests.sort()
for test in failed_tests:
- printMessage('FAILURE', "FAILED", "{}" . format(test))
- return False
- return True
+ print_message("{}" . format(test), 'FAILURE', "FAILED")
+
+ report.output()
+ return not bool(failed_tests)
def create_argparse():
parser = argparse.ArgumentParser()
parser.add_argument("-blender", nargs="+")
parser.add_argument("-testdir", nargs=1)
+ parser.add_argument("-outdir", nargs=1)
parser.add_argument("-idiff", nargs=1)
return parser
@@ -229,7 +433,7 @@ def main():
args = parser.parse_args()
global COLORS
- global BLENDER, ROOT, IDIFF
+ global BLENDER, TESTDIR, IDIFF, OUTDIR
global TEMP_FILE, TEMP_FILE_MASK, TEST_SCRIPT
global VERBOSE
@@ -237,8 +441,12 @@ def main():
COLORS = COLORS_ANSI
BLENDER = args.blender[0]
- ROOT = args.testdir[0]
+ TESTDIR = args.testdir[0]
IDIFF = args.idiff[0]
+ OUTDIR = args.outdir[0]
+
+ if not os.path.exists(OUTDIR):
+ os.makedirs(OUTDIR)
TEMP = tempfile.mkdtemp()
TEMP_FILE_MASK = os.path.join(TEMP, "test")
@@ -248,7 +456,7 @@ def main():
VERBOSE = os.environ.get("BLENDER_VERBOSE") is not None
- ok = run_all_tests(ROOT)
+ ok = run_all_tests(TESTDIR)
# Cleanup temp files and folders
if os.path.exists(TEMP_FILE):
diff --git a/tests/python/render_layer/CMakeLists.txt b/tests/python/render_layer/CMakeLists.txt
index 526b169bc3d..5ff985073e3 100644
--- a/tests/python/render_layer/CMakeLists.txt
+++ b/tests/python/render_layer/CMakeLists.txt
@@ -170,4 +170,6 @@ RENDER_LAYER_TEST(scene_copy_b)
RENDER_LAYER_TEST(scene_copy_c)
RENDER_LAYER_TEST(scene_copy_d)
RENDER_LAYER_TEST(scene_copy_e)
+RENDER_LAYER_TEST(scene_copy_f)
+RENDER_LAYER_TEST(scene_delete)
RENDER_LAYER_TEST(scene_write_read)
diff --git a/tests/python/render_layer/render_layer_common.py b/tests/python/render_layer/render_layer_common.py
index f6e16459ed3..adc32f062ea 100644
--- a/tests/python/render_layer/render_layer_common.py
+++ b/tests/python/render_layer/render_layer_common.py
@@ -55,9 +55,15 @@ def get_layer(layer):
name = layer.get(b'name')
data['name'] = name
- data['active_object'] = layer.get((b'basact', b'object', b'id', b'name'))[2:]
data['engine'] = layer.get(b'engine')
+ active_base = layer.get_pointer(b'basact')
+ if active_base:
+ ob = active_base.get_pointer(b'object')
+ data['active_object'] = ob.get((b'id', b'name'))[2:]
+ else:
+ data['active_object'] = ""
+
objects = []
for link in linkdata_iter(layer, b'object_bases'):
ob = link.get_pointer(b'object')
@@ -747,6 +753,7 @@ class Clay:
layer = self._scene.render_layers.new('Evaluation Test')
layer.collections.unlink(layer.collections[0])
+ self._scene.render_layers.active = layer
bpy.context.workspace.render_layer = layer
# remove all other layers
diff --git a/tests/python/render_layer/test_evaluation_selectability_a.py b/tests/python/render_layer/test_evaluation_selectability_a.py
index 6faebac79aa..393f406eefc 100644
--- a/tests/python/render_layer/test_evaluation_selectability_a.py
+++ b/tests/python/render_layer/test_evaluation_selectability_a.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Selectability Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_selectability_b.py b/tests/python/render_layer/test_evaluation_selectability_b.py
index f2a11865d09..ea05710ebcf 100644
--- a/tests/python/render_layer/test_evaluation_selectability_b.py
+++ b/tests/python/render_layer/test_evaluation_selectability_b.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Selectability Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_selectability_c.py b/tests/python/render_layer/test_evaluation_selectability_c.py
index 5ec6d6e7d9c..8487ee1a8af 100644
--- a/tests/python/render_layer/test_evaluation_selectability_c.py
+++ b/tests/python/render_layer/test_evaluation_selectability_c.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Selectability Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_selectability_d.py b/tests/python/render_layer/test_evaluation_selectability_d.py
index 3ce9c07c907..b2a924dd6bc 100644
--- a/tests/python/render_layer/test_evaluation_selectability_d.py
+++ b/tests/python/render_layer/test_evaluation_selectability_d.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Selectability Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_selectability_e.py b/tests/python/render_layer/test_evaluation_selectability_e.py
index df308845292..70ede58cb9e 100644
--- a/tests/python/render_layer/test_evaluation_selectability_e.py
+++ b/tests/python/render_layer/test_evaluation_selectability_e.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Selectability Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_visibility_a.py b/tests/python/render_layer/test_evaluation_visibility_a.py
index a3a6bb261f5..b9f57539330 100644
--- a/tests/python/render_layer/test_evaluation_visibility_a.py
+++ b/tests/python/render_layer/test_evaluation_visibility_a.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Visibility Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_visibility_b.py b/tests/python/render_layer/test_evaluation_visibility_b.py
index 4f81cd540e2..712cc9bd277 100644
--- a/tests/python/render_layer/test_evaluation_visibility_b.py
+++ b/tests/python/render_layer/test_evaluation_visibility_b.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Visibility Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_visibility_c.py b/tests/python/render_layer/test_evaluation_visibility_c.py
index 6b88f6e3c3a..5e378fb07e3 100644
--- a/tests/python/render_layer/test_evaluation_visibility_c.py
+++ b/tests/python/render_layer/test_evaluation_visibility_c.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Visibility Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_visibility_d.py b/tests/python/render_layer/test_evaluation_visibility_d.py
index b19166bd750..e4f0957bd26 100644
--- a/tests/python/render_layer/test_evaluation_visibility_d.py
+++ b/tests/python/render_layer/test_evaluation_visibility_d.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Visibility Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_visibility_e.py b/tests/python/render_layer/test_evaluation_visibility_e.py
index f9f11cb8f23..33c6d7be111 100644
--- a/tests/python/render_layer/test_evaluation_visibility_e.py
+++ b/tests/python/render_layer/test_evaluation_visibility_e.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Visibility Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_evaluation_visibility_f.py b/tests/python/render_layer/test_evaluation_visibility_f.py
index 497087cb9ca..66948b343cb 100644
--- a/tests/python/render_layer/test_evaluation_visibility_f.py
+++ b/tests/python/render_layer/test_evaluation_visibility_f.py
@@ -26,6 +26,7 @@ class UnitTesting(RenderLayerTesting):
layer = scene.render_layers.new('Visibility Test')
layer.collections.unlink(layer.collections[0])
+ scene.render_layers.active = layer
workspace.render_layer = layer
scene_collection_mom = scene.master_collection.collections.new("Mom")
diff --git a/tests/python/render_layer/test_object_copy.py b/tests/python/render_layer/test_object_copy.py
index 69e05d46140..1e6e9e5b889 100644
--- a/tests/python/render_layer/test_object_copy.py
+++ b/tests/python/render_layer/test_object_copy.py
@@ -42,6 +42,7 @@ class UnitTesting(RenderLayerTesting):
layer.collections.link(subzero)
scene.render_layers.active_index = len(scene.render_layers) - 1
+ bpy.context.workspace.render_layer = bpy.context.scene.render_layers['Fresh new Layer']
if mode == 'DUPLICATE':
# assuming the latest layer is the active layer
diff --git a/tests/python/render_layer/test_object_link_b.py b/tests/python/render_layer/test_object_link_b.py
index e0228594be7..b18eb844fc4 100644
--- a/tests/python/render_layer/test_object_link_b.py
+++ b/tests/python/render_layer/test_object_link_b.py
@@ -19,6 +19,7 @@ class UnitTesting(RenderLayerTesting):
See if we can link objects via bpy.context.scene_collection
"""
import bpy
+ bpy.context.scene.render_layers.active_index = len(bpy.context.scene.render_layers) - 1
bpy.context.workspace.render_layer = bpy.context.scene.render_layers['Viewport']
master_collection = bpy.context.scene_collection
self.do_object_link(master_collection)
diff --git a/tests/python/render_layer/test_operator_context.py b/tests/python/render_layer/test_operator_context.py
index 05a8957fa20..5055d957551 100644
--- a/tests/python/render_layer/test_operator_context.py
+++ b/tests/python/render_layer/test_operator_context.py
@@ -88,6 +88,10 @@ class UnitTesting(RenderLayerTesting):
layer.collections.active_index = 3
self.assertEqual(layer.collections.active.name, 'scorpion')
+ # Change active scene layer (do it for workspace too just to don't get mangled in workspace bugs)
+ scene = bpy.context.scene
+ scene.render_layers.active_index = len(scene.render_layers) - 2
+ self.assertEqual(scene.render_layers.active.name, "Viewport")
bpy.context.workspace.render_layer = bpy.context.scene.render_layers['Viewport']
# old layer
diff --git a/tests/python/render_layer/test_scene_copy_d.py b/tests/python/render_layer/test_scene_copy_d.py
index 54988f49036..f398650eade 100644
--- a/tests/python/render_layer/test_scene_copy_d.py
+++ b/tests/python/render_layer/test_scene_copy_d.py
@@ -16,7 +16,7 @@ from render_layer_common import *
class UnitTesting(RenderLayerTesting):
def test_scene_layers_link(self):
"""
- See if scene copying 'FULL_COPY' is working for scene layers
+ See if scene copying 'LINK_OBJECTS' is working for scene layers
"""
import os
ROOT = self.get_root()
diff --git a/tests/python/render_layer/test_scene_copy_f.py b/tests/python/render_layer/test_scene_copy_f.py
new file mode 100644
index 00000000000..fd4298675f2
--- /dev/null
+++ b/tests/python/render_layer/test_scene_copy_f.py
@@ -0,0 +1,94 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_shared_layer_collections_copy_full(self):
+ """
+ See if scene copying 'FULL_COPY' is keeping collections visibility
+ and selectability.
+ """
+ import os
+ import bpy
+
+ scene = bpy.context.scene
+
+ hide_lookup = [0, 1, 1, 0]
+ hide_lookup_sub = [1, 0, 1]
+
+ hide_select_lookup = [0, 0, 1, 1]
+ hide_select_lookup_sub = [1, 0, 1, 0]
+ new_collections = []
+
+ # clean everything
+ for layer in scene.render_layers:
+ while layer.collections:
+ layer.collections.unlink(layer.collections[0])
+
+ # create new collections
+ for i in range(4):
+ collection = scene.master_collection.collections.new(str(i))
+ new_collections.append(collection)
+
+ for j in range(3):
+ sub_collection = collection.collections.new("{0}:{1}".format(i, j))
+
+ # link to the original scene
+ for layer in scene.render_layers:
+ for i, collection in enumerate(new_collections):
+ layer.collections.link(collection)
+ self.assertEqual(layer.collections[-1], layer.collections[i])
+
+ layer.collections[i].hide = hide_lookup[i]
+ layer.collections[i].hide_select = hide_select_lookup[i]
+
+ for j, sub_collection in enumerate(layer.collections[i].collections):
+ sub_collection.hide = hide_lookup_sub[j]
+ sub_collection.hide_select = hide_select_lookup_sub[j]
+
+ # copy scene
+ bpy.ops.scene.new(type='FULL_COPY')
+ new_scene = bpy.context.scene
+ self.assertNotEqual(scene, new_scene)
+
+ # update depsgrah
+ scene.update() # update depsgraph
+
+ # compare scenes
+ for h, layer in enumerate(scene.render_layers):
+ new_layer = new_scene.render_layers[h]
+
+ for i, collection in enumerate(layer.collections):
+ new_collection = new_layer.collections[i]
+ self.assertEqual(collection.hide, new_collection.hide)
+ self.assertEqual(collection.hide_select, new_collection.hide_select)
+
+ for j, sub_collection in enumerate(layer.collections[i].collections):
+ new_sub_collection = new_collection.collections[j]
+ self.assertEqual(sub_collection.hide, new_sub_collection.hide)
+ self.assertEqual(sub_collection.hide_select, new_sub_collection.hide_select)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()
diff --git a/tests/python/render_layer/test_scene_delete.py b/tests/python/render_layer/test_scene_delete.py
new file mode 100644
index 00000000000..cd59a446c9a
--- /dev/null
+++ b/tests/python/render_layer/test_scene_delete.py
@@ -0,0 +1,39 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_scene_delete(self):
+ """
+ See if a scene can be properly deleted
+ """
+ import bpy
+
+ scene = bpy.context.scene
+ bpy.data.scenes.new('New')
+ bpy.data.scenes.remove(scene)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()