re-work blend file testing

- dependencies are returned as a list
- improve failing to check if the blend creation worked
- add commments explaining strange workarounds
This commit is contained in:
2014-11-21 12:44:55 +01:00
parent b6154953ad
commit 7c2b58caae
2 changed files with 151 additions and 51 deletions

View File

@@ -23,22 +23,26 @@ def _clear_blend():
bpy_data_iter.remove(id_data)
def create_blank():
pass
def create_blank(deps):
assert(isinstance(deps, list))
def create_image_single():
def create_image_single(deps):
import bpy
path = "//my_image.png"
image = bpy.data.images.new(name="MyImage", width=512, height=512)
image.filepath_raw = "//my_image.png"
image.filepath_raw = path
deps.append(bpy.path.abspath(path))
image.file_format = 'PNG'
image.use_fake_user = True
image.save()
if __name__ == "__main__":
import sys
blendfile, create_id, returncode = sys.argv[-3:]
blendfile, blendfile_deps_json, create_id, returncode = sys.argv[-4:]
returncode = int(returncode)
create_fn = globals()[create_id]
@@ -53,7 +57,18 @@ if __name__ == "__main__":
# ----
_clear_blend()
create_fn()
deps = []
create_fn(deps)
if deps:
with open(blendfile_deps_json, 'w') as f:
import json
json.dump(
deps, f, ensure_ascii=False,
check_circular=False,
# optional (pretty)
sort_keys=True, indent=4, separators=(',', ': '),
)
del json
import bpy
bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=blendfile)

View File

@@ -39,6 +39,13 @@ del os, sys, path
# -----------------------------------------
# Ensure we get stdout & stderr on sys.exit
#
# We have this because we override the standard output,
# _AND_ during this state a command may call `sys.exit`
# In this case, we the output is hidden which is very annoying.
#
# So override `sys.exit` with one that prints to the original
# stdout/stderr on exit.
if 1:
import sys
@@ -72,6 +79,13 @@ if 1:
# --------------------------------------------
# Don't Exit when argparse fails to parse args
#
# Argparse can call `sys.exit` if the wrong args are given.
# This messes with testing, which we want to keep the process running.
#
# This monkey-patches in an exist function which simply raises an exception.
# We could do something a bit nicer here,
# but for now just use a basic exception.
import argparse
def argparse_fake_exit(self, status, message):
sys.__stdout__.write(message)
@@ -276,6 +290,44 @@ def file_quick_touch(path, filepart=None, times=None):
os.utime(path, times)
def blendfile_template_create(blendfile, create_id, deps):
returncode_test = 123
blendfile_deps_json = os.path.join(TEMP, "blend_template_deps.json")
os.makedirs(os.path.dirname(blendfile), exist_ok=True)
stdout, stderr, returncode = run(
("blender",
"--background",
"--factory-startup",
"-noaudio",
"--python",
os.path.join(CURRENT_DIR, "blendfile_templates.py"),
"--",
blendfile,
blendfile_deps_json,
create_id,
str(returncode_test),
))
if os.path.exists(blendfile_deps_json):
import json
with open(blendfile_deps_json, 'r') as f:
deps[:] = json.load(f)
os.remove(blendfile_deps_json)
else:
deps.clear()
if returncode != returncode_test:
# verbose will have already printed
if not VERBOSE:
print(">>> ", args_as_string(cmd))
sys.stdout.write(" stdout: %s\n" % stdout.strip())
sys.stdout.write(" stderr: %s\n" % stderr.strip())
sys.stdout.write(" return: %d\n" % returncode)
return False
else:
return True
def wait_for_input():
"""for debugging,
so we can inspect the state of the system before the test finished.
@@ -347,7 +399,8 @@ def server(mode='testing', debug=False):
return p
def global_setup():
def global_setup(use_server=True):
data = []
if VERBOSE:
# for server
@@ -357,14 +410,20 @@ def global_setup():
shutil.rmtree(TEMP_SERVER, ignore_errors=True)
shutil.rmtree(TEMP, ignore_errors=True)
p = server()
data = p
if use_server:
p = server()
data.append(p)
return data
def global_teardown(data):
p = data
p.terminate()
def global_teardown(data, use_server=True):
if use_server:
p = data.pop(0)
p.terminate()
shutil.rmtree(TEMP_SERVER, ignore_errors=True)
shutil.rmtree(TEMP, ignore_errors=True)
@@ -375,6 +434,27 @@ def global_teardown(data):
import unittest
class BamSimpleTestCase(unittest.TestCase):
""" Basic testcase, only make temp dirs.
"""
def setUp(self):
# for running single tests
if __name__ != "__main__":
self._data = global_setup(use_server=False)
if not os.path.isdir(TEMP):
os.makedirs(TEMP)
def tearDown(self):
# input('Wait:')
shutil.rmtree(TEMP)
# for running single tests
if __name__ != "__main__":
global_teardown(self._data, use_server=False)
class BamSessionTestCase(unittest.TestCase):
def setUp(self):
@@ -536,60 +616,63 @@ class BamCommitTest(BamSessionTestCase):
stdout, stderr = bam_run(["checkout", "testfile.txt"], proj_path)
self.assertEqual("", stderr)
# wait_for_input()
self.assertEqual(True, os.path.exists(os.path.join(proj_path, "testfile/testfile.txt")))
self.assertTrue(os.path.exists(os.path.join(proj_path, "testfile/testfile.txt")))
file_data_test = file_quick_read(os.path.join(proj_path, "testfile/testfile.txt"))
self.assertEqual(file_data, file_data_test)
class BamBlendTest(BamSessionTestCase):
def __init__(self, *args):
self.init_defaults()
super().__init__(*args)
@staticmethod
def create_blend_id(blendfile, create_id, returncode_test):
os.makedirs(os.path.dirname(blendfile), exist_ok=True)
stdout, stderr, returncode = run(
("blender",
"--background",
"--factory-startup",
"-noaudio",
"--python",
os.path.join(CURRENT_DIR, "blendfile_templates.py"),
"--",
blendfile,
create_id,
str(returncode_test),
))
return stdout, stderr, returncode
class BamBlendTest(BamSimpleTestCase):
def test_create_all(self):
""" This simply tests all the create functions run without error.
"""
import blendfile_templates
returncode_test = 42
TEMP_SESSION = os.path.join(TEMP, "blend_file_template")
def iter_files_session():
for dirpath, dirnames, filenames in os.walk(TEMP_SESSION):
for filename in filenames:
filepath = os.path.join(dirpath, filename)
yield filepath
for create_id, create_fn in blendfile_templates.__dict__.items():
if create_id.startswith("create_"):
if create_fn.__class__.__name__ == "function":
blendfile = os.path.join(TEMP, create_id + ".blend")
if (create_id.startswith("create_") and
create_fn.__class__.__name__ == "function"):
stdout, stderr, returncode = self.create_blend_id(blendfile, create_id, returncode_test)
os.makedirs(TEMP_SESSION)
self.assertEqual(b'', stderr)
self.assertEqual(True, os.path.exists(blendfile))
self.assertEqual(returncode, returncode_test)
with open(blendfile, 'rb') as blendfile_handle:
self.assertEqual(b'BLENDER', blendfile_handle.read(7))
os.remove(blendfile)
blendfile = os.path.join(TEMP, create_id + ".blend")
deps = []
if not blendfile_template_create(blendfile, create_id, deps):
# self.fail("blend file couldn't be create")
# ... we want to keep running
self.assertTrue(False, True) # GRR, a better way?
shutil.rmtree(TEMP_SESSION)
continue
self.assertTrue(os.path.exists(blendfile))
with open(blendfile, 'rb') as blendfile_handle:
self.assertEqual(b'BLENDER', blendfile_handle.read(7))
os.remove(blendfile)
# check all deps are accounted for
for f in deps:
self.assertTrue(os.path.exists(f))
for f in iter_files_session():
self.assertIn(f, deps)
shutil.rmtree(TEMP_SESSION)
def test_empty(self):
blendfile = os.path.join(TEMP, "test.blend")
returncode_test = 13
stdout, stderr, returncode = self.create_blend_id(blendfile, "create_blank", returncode_test)
self.assertEqual(True, os.path.exists(blendfile))
self.assertEqual(returncode_test, returncode)
if not blendfile_template_create(blendfile, "create_blank", []):
self.fail("blend file couldn't be created")
return
self.assertTrue(os.path.exists(blendfile))
class BamDeleteTest(BamSessionTestCase):
@@ -614,7 +697,9 @@ class BamDeleteTest(BamSessionTestCase):
# now do a real commit
returncode_test = 42
blendfile = os.path.join(session_path, "testfile.blend")
stdout, stderr, returncode = BamBlendTest.create_blend_id(blendfile, "create_blank", returncode_test)
if not blendfile_template_create(blendfile, "create_blank", []):
self.fail("blend file couldn't be created")
return
stdout, stderr = bam_run(["commit", "-m", "tests message"], session_path)
self.assertEqual("", stderr)