"""Интеграционный тест pyfglair.Session против mock_ac.py (без железа).""" from __future__ import annotations import asyncio import time from pyfglair import Config, Prop, Session, State async def _wait_state(states: asyncio.Queue, target: State, timeout: float = 10.0): deadline = time.monotonic() + timeout while True: remaining = deadline - time.monotonic() assert remaining > 0, f"не дождались {target!r}" state, error = await asyncio.wait_for(states.get(), remaining) if state == target: return state, error async def _wait_prop(events: asyncio.Queue, prop: Prop, timeout: float = 10.0): deadline = time.monotonic() + timeout while True: remaining = deadline - time.monotonic() assert remaining > 0, f"не дождались свойства {prop!r}" event = await asyncio.wait_for(events.get(), remaining) if event.prop == prop: return event async def test_session_against_mock(mock_ac, ac_env): proc = mock_ac() states: asyncio.Queue = asyncio.Queue() events: asyncio.Queue = asyncio.Queue() cfg = Config( host="127.0.0.1", device_port=proc.port, dsn=ac_env["dsn"], lanip_key=ac_env["key"], lanip_key_id=ac_env["key_id"], keepalive_ms=1000, ) session = Session( cfg, on_state=lambda st, err: states.put_nowait((st, err)), on_property=lambda ev: events.put_nowait(ev), ) assert session.start() try: state, error = await _wait_state(states, State.ONLINE) assert state == State.ONLINE assert error == 0 session.batch_begin() assert session.get_prop(Prop.OPERATION_MODE) assert session.get_prop(Prop.FAN_SPEED) assert session.batch_commit() op = await _wait_prop(events, Prop.OPERATION_MODE) assert op.value.int_value == 6 assert op.cmd_id >= 0 fan = await _wait_prop(events, Prop.FAN_SPEED) assert fan.value.int_value == 4 assert session.set_int(Prop.FAN_SPEED, 2) cached = session.cached(Prop.FAN_SPEED) assert cached is not None and cached.int_value == 2 assert proc.wait_line("CMD SET fan_speed=2", 10) is not None finally: await session.async_stop() assert session.closed assert session.state == State.IDLE assert proc.wait_line("DELETE", 10) is not None async def test_callbacks_run_in_loop_thread(mock_ac, ac_env): proc = mock_ac() loop = asyncio.get_running_loop() seen: list[object] = [] cfg = Config( host="127.0.0.1", device_port=proc.port, dsn=ac_env["dsn"], lanip_key=ac_env["key"], lanip_key_id=ac_env["key_id"], ) session = Session(cfg, on_state=lambda st, err: seen.append(asyncio.get_running_loop())) session.start() try: deadline = time.monotonic() + 10 while not seen: assert time.monotonic() < deadline, "колбэки не пришли" await asyncio.sleep(0.05) finally: await session.async_stop() assert all(item is loop for item in seen)