diff options
-rw-r--r-- | source/tests/CMakeLists.txt | 14 | ||||
-rw-r--r-- | source/tests/bl_load_addons.py | 78 | ||||
-rw-r--r-- | source/tests/bl_load_py_modules.py | 145 |
3 files changed, 237 insertions, 0 deletions
diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index a341caac1d0..e9837dd354f 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -44,6 +44,20 @@ endif() set(TEST_BLENDER_EXE ${TEST_BLENDER_EXE} --background --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts) + +# ------------------------------------------------------------------------------ +# GENERAL PYTHON CORRECTNESS TESTS +add_test(script_load_addons ${TEST_BLENDER_EXE} + --python ${CMAKE_CURRENT_LIST_DIR}/bl_load_addons.py +) + +add_test(script_load_modules ${TEST_BLENDER_EXE} + --python ${CMAKE_CURRENT_LIST_DIR}/bl_load_py_modules.py +) + +# ------------------------------------------------------------------------------ +# IO TESTS + # OBJ Import tests add_test(import_obj_cube ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- diff --git a/source/tests/bl_load_addons.py b/source/tests/bl_load_addons.py new file mode 100644 index 00000000000..5bd83abbcb6 --- /dev/null +++ b/source/tests/bl_load_addons.py @@ -0,0 +1,78 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +# simple script to enable all addons, and disable + +import bpy +import addon_utils + +import sys +import imp + + +def reload_addons(do_reload=True, do_reverse=True): + modules = addon_utils.modules({}) + modules.sort(key=lambda mod: mod.__name__) + addons = bpy.context.user_preferences.addons + + # first disable all + for mod_name in list(addons.keys()): + addon_utils.disable(mod_name) + + assert(bool(addons) == False) + + # Run twice each time. + for i in (0, 1): + for mod in modules: + mod_name = mod.__name__ + print("\tenabling:", mod_name) + addon_utils.enable(mod_name) + assert(mod_name in addons) + + for mod in addon_utils.modules({}): + mod_name = mod.__name__ + print("\tdisabling:", mod_name) + addon_utils.disable(mod_name) + assert(not (mod_name in addons)) + + # now test reloading + if do_reload: + imp.reload(sys.modules[mod_name]) + + if do_reverse: + # incase order matters when it shouldnt + modules.reverse() + + +def main(): + reload_addons(do_reload=False, do_reverse=False) + reload_addons(do_reload=False, do_reverse=True) + reload_addons(do_reload=True, do_reverse=True) + + +if __name__ == "__main__": + + # So a python error exits(1) + try: + main() + except: + import traceback + traceback.print_exc() + sys.exit(1) diff --git a/source/tests/bl_load_py_modules.py b/source/tests/bl_load_py_modules.py new file mode 100644 index 00000000000..5a65578d8d3 --- /dev/null +++ b/source/tests/bl_load_py_modules.py @@ -0,0 +1,145 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +# simple script to enable all addons, and disable + +import bpy +import addon_utils + +import sys +import os +import imp + + +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 + + for filename in filenames: + filepath = join(dirpath, filename) + if filename_check is None or filename_check(filepath): + yield filepath + + +def load_addons(): + modules = addon_utils.modules({}) + modules.sort(key=lambda mod: mod.__name__) + addons = bpy.context.user_preferences.addons + + # first disable all + for mod_name in list(addons.keys()): + addon_utils.disable(mod_name) + + assert(bool(addons) == False) + + for mod in modules: + mod_name = mod.__name__ + addon_utils.enable(mod_name) + assert(mod_name in addons) + + +def load_modules(): + modules = [] + module_paths = [] + + # paths blender stores scripts in. + paths = bpy.utils.script_paths() + + # + # find all sys.path we added + for script_path in paths: + for mod_dir in sys.path: + if mod_dir.startswith(script_path): + module_paths.append(mod_dir) + + # + # collect modules from our paths. + for mod_dir in module_paths: + # print("mod_dir", mod_dir) + for mod, mod_full in bpy.path.module_names(mod_dir): + modules.append(__import__(mod)) + + # + # now submodules + for m in modules: + filepath = m.__file__ + if os.path.basename(filepath).startswith("__init__."): + mod_dir = os.path.dirname(filepath) + for submod, submod_full in bpy.path.module_names(mod_dir): + # fromlist is ignored, ugh. + mod_name_full = m.__name__ + "." + submod + __import__(mod_name_full) + mod_imp = sys.modules[mod_name_full] + + # check we load what we ask for. + assert(os.path.samefile(mod_imp.__file__, submod_full)) + + modules.append(mod_imp) + + # + # check which filepaths we didnt load + source_files = [] + for mod_dir in module_paths: + source_files.extend(source_list(mod_dir, filename_check=lambda f: f.endswith(".py"))) + + source_files = list(set(source_files)) + source_files.sort() + + # + # remove loaded files + loaded_files = list({m.__file__ for m in modules}) + loaded_files.sort() + + 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, + ] + + for f in source_files: + ok = False + for ignore in ignore_paths: + if ignore in f: + ok = True + if not ok: + raise Exception("Source file %r not loaded in test" % f) + + print("loaded %d modules" % len(loaded_files)) + + +def main(): + load_addons() + load_modules() + +if __name__ == "__main__": + # So a python error exits(1) + try: + main() + except: + import traceback + traceback.print_exc() + sys.exit(1) |