all repos — rastro @ 303f75c7f98bcf857e2ef49ec4c4489ce9eb333b

BitTorrent tracker!

tests/unit/test_smart_list.py (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
"""Smart list diversity selection."""

from __future__ import annotations

from datetime import UTC, datetime, timedelta

import pytest
from app.db.models import ProbeResult, Tracker
from app.services.smart_list import SmartListFilters, build_smart_list
from sqlalchemy.ext.asyncio import AsyncSession


async def _seed_tracker(
    session: AsyncSession,
    *,
    url: str,
    fp: str,
    asn: int | None,
    latency: float,
) -> Tracker:
    now = datetime.now(UTC)
    t = Tracker(
        canonical_url=url,
        scheme="udp",
        hostname=url.split("://")[1].split(":")[0],
        port=80,
        path="/announce",
        current_status="up",
        first_seen_at=now - timedelta(days=30),
        last_seen_at=now,
        last_checked_at=now,
        last_latency_ms=latency,
        consecutive_failures=0,
        infrastructure_fingerprint=fp,
        asn=asn,
        supports_ipv4=True,
        supports_ipv6="not_tested",
    )
    session.add(t)
    await session.flush()
    for i in range(12):
        session.add(
            ProbeResult(
                tracker_id=t.id,
                checked_at=now - timedelta(hours=i),
                status="up",
                latency_ms=latency,
                response_valid=True,
            )
        )
    await session.commit()
    return t


@pytest.mark.asyncio
async def test_smart_list_diversity(session: AsyncSession):
    await _seed_tracker(session, url="udp://a1.example:80/announce", fp="fp1", asn=100, latency=50)
    await _seed_tracker(session, url="udp://a2.example:80/announce", fp="fp1", asn=100, latency=40)
    await _seed_tracker(session, url="udp://b1.example:80/announce", fp="fp2", asn=100, latency=60)
    await _seed_tracker(session, url="udp://c1.example:80/announce", fp="fp3", asn=200, latency=70)

    entries = await build_smart_list(
        session, SmartListFilters(min_uptime=0.5, limit=20, diversity=True)
    )
    urls = [e.tracker.canonical_url for e in entries]
    # only one of fp1
    assert sum(1 for u in urls if u.startswith("udp://a")) == 1
    # asn 100 at most twice
    asn100 = [e for e in entries if e.tracker.asn == 100]
    assert len(asn100) <= 2
    assert "udp://c1.example:80/announce" in urls