66 lines
2.5 KiB
Python
66 lines
2.5 KiB
Python
# -*- 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} неверна — данные искажены")
|