# -*- coding: utf-8 -*- """Автотесты лабораторной 5 (синхронизация).""" import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from conftest import load_solution # noqa: E402 def test_variant_number_set(): mod = load_solution("lab05_sync") assert 1 <= getattr(mod, "VARIANT_NUMBER", 0) <= 20, ( "Укажите свой VARIANT_NUMBER (1..20) в solution.py") def test_race_fixed_exact(): """С Lock результат точен при любых запусках.""" mod = load_solution("lab05_sync") for _ in range(3): got, expected = mod.race_fixed(6, 10_000) assert got == expected, ( f"race_fixed потерял обновления: {got} из {expected} — " "Lock не защищает счётчик") def test_race_demo_type(): mod = load_solution("lab05_sync") got, expected = mod.race_demo(4, 5_000) assert isinstance(got, int) and isinstance(expected, int) assert expected == 20_000 assert 0 < got <= expected def test_semaphore_limits(): """max_concurrent=2 на 10 запросах по 0.1 c должно занять ~0.5 c (не ~0.1).""" mod = load_solution("lab05_sync") res, t = mod.semaphore_limiter(10, 0.1, 2) assert len(res) == 10 assert t >= 0.45, ( f"выполнено за {t:.2f} c — лимит {2} одновременных не соблюдается") # и параллельность работает: на limiter=10 было бы ~0.1 c res2, t2 = mod.semaphore_limiter(10, 0.1, 10) assert t2 < t * 0.6, "при большем лимите время должно заметно упасть" def test_producer_consumer_no_deadlock(): mod = load_solution("lab05_sync") import signal def handler(signum, frame): raise TimeoutError("producer_consumer не завершился — дедлок!") try: signal.signal(signal.SIGALRM, handler) signal.alarm(30) processed, total_sum = mod.producer_consumer(2, 3, 30) signal.alarm(0) except (AttributeError, ValueError): # Windows: SIGALRM нет — просто вызываем processed, total_sum = mod.producer_consumer(2, 3, 30) assert processed == 30, f"обработано {processed} из 30 — задачи потерялись" assert total_sum == sum(range(30)), ( f"сумма {total_sum} неверна — данные искажены")