chore: Update version to 0.12.11, upgrade BlendJob wheel to 0.1.13, and enhance documentation for environment installation and model management

This commit is contained in:
2026-08-18 13:34:22 +08:00
parent 6e6dd60a88
commit 9dfa49602c
15 changed files with 176 additions and 62 deletions

View File

@@ -261,7 +261,7 @@ class AddonTest(unittest.TestCase):
self.assertIn("--config", command)
self.assertNotIn("--venv-dir", command)
self.assertNotIn("--models-dir", command)
self.assertEqual(command[command.index("--stages") + 1], "1")
self.assertNotIn("--stages", command)
def test_runtime_exposes_declared_environment_and_post_install(self):
runtime = self.addon.runtime
@@ -372,12 +372,14 @@ class AddonTest(unittest.TestCase):
controller._update_post_progress(
{"job_id": "first", "job_type": "download-model", "progress": 1.0}
)
first_stage = controller.post_status["stage"]
self.assertEqual(controller.post_status["job_id"], "first")
controller._update_post_progress(
{"job_id": "second", "job_type": "download-model", "progress": 0.1}
)
self.assertGreater(controller.post_status["stage"], first_stage)
self.assertEqual(controller.post_status["job_id"], "second")
self.assertEqual(controller.post_status["progress"], 0.1)
self.assertNotIn("stage", controller.post_status)
self.assertNotIn("stages", controller.post_status)
def test_conversion_model_lists_default_to_moge2_vits(self):
@@ -442,7 +444,94 @@ class AddonTest(unittest.TestCase):
("snapform.download_required_models", True),
)
self.assertIn(("snapform.convert_to_depth_plane", False), calls)
self.assertIn(("snapform.convert_to_surface", True), calls)
self.assertIn(("snapform.convert_to_surface", False), calls)
self.assertIn(("snapform.remove_image_background", False), calls)
def test_image_menu_keeps_disabled_features_when_environment_is_missing(self):
calls = []
class Layout:
operator_context = ""
enabled = True
def __init__(self, enabled=True):
self.enabled = enabled
def row(self):
return Layout(self.enabled)
def operator(self, identifier, **_options):
calls.append((identifier, self.enabled))
return SimpleNamespace()
def separator(self):
calls.append(("separator", self.enabled))
menu = self.addon.SnapFormImageMenu()
menu.layout = Layout()
with patch.object(
self.addon.runtime,
"environment_ready",
return_value=False,
), patch(
"snapform.properties.required_models_ready",
return_value=False,
):
menu.draw(None)
self.assertEqual(calls[0], ("snapform.install_environment", True))
self.assertEqual(
calls[1],
("snapform.install_environment_mirror", True),
)
self.assertNotIn(("snapform.download_required_models", True), calls)
self.assertIn(("snapform.convert_to_depth_plane", False), calls)
self.assertIn(("snapform.convert_to_surface", False), calls)
self.assertIn(("snapform.remove_image_background", False), calls)
def test_image_operators_require_environment_and_required_models(self):
context = SimpleNamespace(
object=SimpleNamespace(data=SimpleNamespace()),
)
operators = (
(self.addon.image_depth, self.addon.ConvertToDepthPlane),
(self.addon.image_mesh, self.addon.ConvertToSurface),
(self.addon.image_depth, self.addon.RemoveImageBackground),
)
states = (
(False, True, False),
(True, False, False),
(True, True, True),
)
for environment_ready, models_ready, expected in states:
with self.subTest(
environment_ready=environment_ready,
models_ready=models_ready,
expected=expected,
), patch.object(
self.addon.runtime,
"environment_ready",
return_value=environment_ready,
), patch.object(
self.addon.runtime,
"server_busy",
return_value=False,
), patch(
"snapform.properties.required_models_ready",
return_value=models_ready,
):
for module, operator in operators:
with self.subTest(operator=operator.__name__), patch.object(
module,
"is_image_empty",
return_value=True,
), patch.object(
module,
"video_total_frames",
return_value=1,
):
self.assertEqual(operator.poll(context), expected)
def test_ui_reads_required_model_files_without_starting_server(self):
properties = importlib.import_module("snapform.properties")
@@ -490,8 +579,10 @@ class AddonTest(unittest.TestCase):
)
def test_server_request_returns_job_result_and_calls_response(self):
blendjob = importlib.import_module("blendjob")
controller = blendjob.ServerController.__new__(blendjob.ServerController)
controller_type = importlib.import_module(
"blendjob.controller"
).ServerController
controller = controller_type.__new__(controller_type)
statuses = iter(
(
{"state": "running", "progress": 0.5},

View File

@@ -73,7 +73,7 @@ class PackTest(unittest.TestCase):
self.assertNotIn("server/jobs.py", names)
self.assertIn("server/__init__.py", names)
self.assertIn(
"wheels/blendjob-0.1.8-py3-none-any.whl",
"wheels/blendjob-0.1.13-py3-none-any.whl",
names,
)
self.assertFalse(

View File

@@ -105,10 +105,10 @@ class ServerTest(unittest.TestCase):
def wait_for_job(self, context, timeout=2.0):
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
if context.snapshot()["state"] in {"succeeded", "failed", "cancelled"}:
return context.snapshot()
if context._snapshot()["state"] in {"succeeded", "failed", "cancelled"}:
return context._snapshot()
time.sleep(0.01)
self.fail(f"Job did not finish: {context.snapshot()}")
self.fail(f"Job did not finish: {context._snapshot()}")
def test_ben2_model_is_reused_for_matching_runtime_key(self):
loads = []
@@ -267,7 +267,7 @@ class ServerTest(unittest.TestCase):
server = self.create_server()
context = server.submit("remove-background", {}, job_id="job")
self.assertIsNotNone(server.cancel("job"))
self.assertTrue(context.is_cancelled())
self.assertTrue(context._is_cancelled())
status = self.wait_for_job(context)
self.assertEqual(status["state"], "cancelled")
@@ -291,8 +291,8 @@ class ServerTest(unittest.TestCase):
self.assertRegex(context.job_id, r"^[0-9a-f]{32}$")
self.assertEqual(context.directory.name, context.job_id)
self.assertEqual(context.snapshot()["state"], "succeeded")
self.assertEqual(context.snapshot()["progress"], 1.0)
self.assertEqual(context._snapshot()["state"], "succeeded")
self.assertEqual(context._snapshot()["progress"], 1.0)
def test_runtime_storage_root_owns_the_jobs_directory(self):
storage_root = self.storage_root
@@ -308,7 +308,7 @@ class ServerTest(unittest.TestCase):
self.assertEqual(server.jobs_directory, storage_root / "jobs")
self.assertEqual(context.storage_root, storage_root.resolve())
self.assertEqual(context.snapshot()["result"], {"value": 42})
self.assertEqual(context._snapshot()["result"], {"value": 42})
def test_job_server_owns_and_clears_shared_resources(self):
events = []