ad049d12e4
阻止不完整标定配置生成 Z 目标,同步当前测点姿态,并将复核文件校验移到后台。通过 476 项全量测试、53 项最终定向复验和代码检查。
87 lines
2.6 KiB
Python
87 lines
2.6 KiB
Python
"""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 == []
|