Newer
Older
gn-synapse-client-py / examples / plain / smoke.py
@Eugene Sukhodolskiy Eugene Sukhodolskiy 1 day ago 3 KB Initial client library skeleton (v0.1.0)
"""Интеграционный смок против живого Synapse.

Запуск (токен выдаёт `create-key` на сервере, он печатается один раз):

    SYNAPSE_URL=http://localhost:8013 SYNAPSE_API_KEY=syn_... \
        python examples/plain/smoke.py

Внутри контейнера api URL — http://localhost:8000. Источник и тип
(source libtest, тип ping/done) должны быть зарегистрированы на сервере.
"""

from __future__ import annotations

import os
import sys
import time

from gnexus_synapse import (
    SynapseClient,
    SynapseConfigError,
    SynapseConnectionError,
    SynapseForbiddenError,
    SynapseNotFoundError,
    SynapseValidationError,
)

# уникальный на прогон: дедуп-окно сервера 24 ч, повтор полный — смок увидит не queued
DEDUP = f"client-smoke-{int(time.time())}"


def main() -> int:
    client = SynapseClient()
    print(" health:", client.health())

    event = client.send("libtest", "ping", "done", payload={"user_id": "mcp"},
                        dedup_key=DEDUP)
    print(f" send: id={event.id} status={event.status}")
    assert event.status == "queued" and not event.deduplicated

    repeat = client.send("libtest", "ping", "done", payload={"user_id": "mcp"},
                         dedup_key=DEDUP)
    print(f" repeat: id={repeat.id} deduplicated={repeat.deduplicated}")
    assert repeat.deduplicated and repeat.id == event.id  # дедуп вернул первое событие

    status = client.status(event.id)
    print(f" status: {status.status}; доставки:")
    for d in status.deliveries:
        target = f" → {d.target}" if d.target else ""
        err = f" ({d.error})" if d.error else ""
        print(f"   {d.channel}{target}: {d.status} ×{d.attempts}{err}")

    try:
        client.send("wrong-source", "ping", "done")  # анти-спуфинг сервера
    except SynapseForbiddenError as ex:
        print(f" 403 пойман (анти-спуфинг): {ex.detail}")
    else:
        print(" ОШИБКА: 403 не получен")
        return 1

    try:
        client.status("00000000-0000-0000-0000-000000000000")
    except SynapseNotFoundError:
        print(" 404 пойман (чужой/несуществующий id)")

    # валидный конверт на недоступный хост → типизированное соединение-исключение
    try:
        SynapseClient("http://localhost:9999", "syn_x", timeout=1.0).send("libtest", "a", "b")
    except SynapseConnectionError as ex:
        print(f" соединение-ошибка поймана: {ex}")
    except SynapseConfigError as ex:
        print(f" config-ошибка поймана: {ex}")
    except SynapseValidationError as ex:
        print(f" локальная валидация поймана: {ex}")

    print(" ALL OK")
    return 0


if __name__ == "__main__":
    if not os.environ.get("SYNAPSE_API_KEY"):
        print("задайте SYNAPSE_URL и SYNAPSE_API_KEY", file=sys.stderr)
        sys.exit(2)
    sys.exit(main())