修复 Autocal 压头配置、姿态保存与复核性能

阻止不完整标定配置生成 Z 目标,同步当前测点姿态,并将复核文件校验移到后台。通过 476 项全量测试、53 项最终定向复验和代码检查。
This commit is contained in:
ykcheungab
2026-10-15 07:51:39 +08:00
parent bcc55a3b97
commit ad049d12e4
16 changed files with 388 additions and 38 deletions
+86
View File
@@ -0,0 +1,86 @@
"""Recording integrity work must leave the UI thread free and report failures."""
import threading
from PySide6.QtCore import QObject, QTimer, Slot, QCoreApplication, QEvent, QThreadPool
from PySide6.QtTest import QTest
from orisys_autocal.ui.review_job import ReviewJob
def test_review_job_runs_off_thread_and_keeps_qt_responsive(qt_app):
started, release = threading.Event(), threading.Event()
main_thread = threading.get_ident()
results, ticks = [], []
class Receiver(QObject):
@Slot(object, object)
def receive(self, value, error):
results.append((value, error, threading.get_ident()))
receiver = Receiver()
def action():
started.set()
assert release.wait(3)
return threading.get_ident()
job = ReviewJob(action, receiver.receive)
job.start()
try:
assert started.wait(2)
QTimer.singleShot(0, lambda: ticks.append(True))
QTest.qWait(20)
assert ticks == [True] and results == []
finally:
release.set()
for _ in range(100):
if results:
break
QTest.qWait(10)
assert len(results) == 1
assert results[0][0] != main_thread
assert results[0][1] is None and results[0][2] == main_thread
def test_unexpected_review_job_failure_returns_to_receiver(qt_app):
results = []
class Receiver(QObject):
@Slot(object, object)
def receive(self, value, error):
results.append((value, error))
receiver = Receiver()
def action():
raise RuntimeError("decoder failed")
job = ReviewJob(action, receiver.receive)
job.start()
for _ in range(100):
if results:
break
QTest.qWait(10)
assert results == [(None, "decoder failed")]
def test_review_job_can_finish_after_its_receiver_is_destroyed(qt_app):
started, release, finished = threading.Event(), threading.Event(), threading.Event()
results = []
class Receiver(QObject):
@Slot(object, object)
def receive(self, value, error):
results.append((value, error))
receiver = Receiver()
def action():
started.set()
assert release.wait(3)
finished.set()
return "done"
job = ReviewJob(action, receiver.receive)
job.start()
try:
assert started.wait(2)
receiver.deleteLater()
QCoreApplication.sendPostedEvents(receiver, QEvent.Type.DeferredDelete)
finally:
release.set()
assert QThreadPool.globalInstance().waitForDone(3000)
qt_app.processEvents()
assert finished.is_set() and results == []