Files
camoufox/pythonlib/tests/test_geoip_sources.py
f36390a19e feat(geoip): make GeoIP AIO the default source, deprecate GeoLite2 (#820)
The default GeoIP source was MaxMind GeoLite2 via sapics/ip-location-db,
whose URLs kept serving the 2026-06-17 build after that project moved to
GitHub Releases (found in #815). GeoIP AIO (daijro/geoip-all-in-one)
resolves timezones more accurately on real proxy IPs and is rebuilt weekly.

- repos.yml: AIO is the default; GeoLite2 is `deprecated: true`, with the
  Releases URLs from #815 so it still works when picked by name.
- A cache holding a deprecated source it was not explicitly given
  (`camoufox set --geoip` or the GUI) moves to the default and drops the
  old database. An explicit choice is kept, with a FutureWarning.
- needs_update() reads the database's build date instead of the file age:
  refresh once the build is over 8 days old, re-checking at most daily,
  and warn when a fresh download is over 30 days old (a frozen source).
- get_geolocation(geoip_db=...) now reads that source's own database
  rather than the active one's, and no longer makes it the active one.
- tests/test_geoip_sources.py (from #815) downloads every non-deprecated
  source and fails when its build is stale; tests.yml installs the geoip
  extra so it runs, and so gates every release.
- TypeScript twin updated to match; goldens answer in both layouts.

Co-authored-by: lp177 <57773165+lp177@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 20:02:52 +00:00

44 lines
1.7 KiB
Python

"""Every GeoIP source camoufox offers must be serving a current build.
The launcher always downloads a source's newest build, so a source that stops
publishing leaves every user on stale data with no error: GeoLite2's URLs
served the 2026-06-17 build for months after sapics/ip-location-db moved to
GitHub Releases (found in daijro/camoufox#815, which this test comes from).
This suite runs in tests.yml, which gates every release.
"""
import time
import pytest
from camoufox import geolocation
maxminddb = pytest.importorskip("maxminddb")
MAX_AGE_DAYS = 30
SOURCES = [repo["name"] for repo in geolocation._load_geoip_repos()[0] if not repo.get("deprecated")]
@pytest.mark.parametrize("name", SOURCES)
def test_source_serves_a_current_build(name, tmp_path, monkeypatch):
monkeypatch.setattr(geolocation, "GEOIP_DIR", tmp_path)
monkeypatch.setattr(geolocation, "MMDB_DIR", tmp_path / "mmdb")
monkeypatch.setattr(geolocation, "GEOIP_CONFIG", tmp_path / "config.yml")
geolocation.download_mmdb(name)
databases = sorted((tmp_path / "mmdb").glob("*.mmdb"))
assert databases, f"{name} downloaded no database"
for database in databases:
with maxminddb.open_database(str(database)) as reader:
age_days = (time.time() - reader.metadata().build_epoch) / 86400
record = reader.get("8.8.8.8")
assert age_days < MAX_AGE_DAYS, (
f"{name}: {database.name} was built {age_days:.0f} days ago, its source is no longer updated"
)
config = geolocation._get_geoip_config_by_name(name)
assert geolocation._find_in(record, config["paths"]["iso_code"]) == "US", (
f"{name}: the configured paths do not read this database"
)