Files
MoviePilot/tests/test_singleton_thread_safety.py
T

42 lines
1.3 KiB
Python

import threading
from app.foundation.singleton import Singleton, SingletonClass
def _construct_concurrently(singleton_type, count: int = 16):
"""让多个线程同时越过起跑线,放大首次构造竞态。"""
barrier = threading.Barrier(count)
instances = []
def construct() -> None:
barrier.wait()
instances.append(singleton_type())
threads = [threading.Thread(target=construct) for _ in range(count)]
for thread in threads:
thread.start()
for thread in threads:
thread.join(timeout=5)
assert not thread.is_alive()
return instances
def test_parameterized_singleton_first_construction_is_single_flight():
"""同一参数的并发首次构造只能发布一个完整实例。"""
class _ParameterizedSingleton(metaclass=Singleton):
pass
instances = _construct_concurrently(_ParameterizedSingleton)
assert len({id(instance) for instance in instances}) == 1
def test_class_singleton_first_construction_is_single_flight():
"""按类单例的并发首次构造只能发布一个完整实例。"""
class _ClassSingleton(metaclass=SingletonClass):
pass
instances = _construct_concurrently(_ClassSingleton)
assert len({id(instance) for instance in instances}) == 1