Files
fangke/server/tracker/tests/test_stats.py
T
浅念 cc1ea6805b feat: 日聚合服务与命令 + 索引迁移打包(Task3 审查结论)
- refresh_daily:按上海自然日聚合 pv/uv/sessions/new_visitors,update_or_create 幂等
- refresh_stats 管理命令:回刷近 N 天(生产由 1Panel 每日 00:10 调度,见 Task 22)
- 索引打包(0002):Event/VisitSession 增加 (site, 时间) 日聚合索引;
  删 5 个冗余单列 FK 索引(Event.site/session、VisitSession.site/visitor、DailyStat.site),
  保留 Event.visitor/Visitor.site;sqlite PRAGMA 实证级联索引完整、EXPLAIN 走新索引
- test_models:IntegrityError 断言收紧 + Site 级联删除测试

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-15 13:38:01 +08:00

31 lines
1.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from datetime import timedelta
from django.utils import timezone
from tracker.models import Site, Visitor, VisitSession, Event
from tracker.services.stats import refresh_daily
# 用上海本地时刻做基准:refresh_daily 的日界是上海自然日(make_aware),
# 若直接用 UTC 的 timezone.now(),在本地 00:00-08:00 之间跑测试时 NOW.date() 会错一天
NOW = timezone.localtime(timezone.now())
YESTERDAY = NOW - timedelta(days=1)
def _mk(site, vid, sid, day, n_events, stay=0):
v, _ = Visitor.objects.get_or_create(site=site, visitor_id=vid)
sess = VisitSession.objects.create(site=site, visitor=v, session_id=sid,
started_at=day, ended_at=day + timedelta(minutes=5),
stay_ms=stay, event_count=n_events)
for i in range(n_events):
Event.objects.create(site=site, visitor=v, session=sess, event_id=f"{vid}-{sid}-{day:%Y%m%d}-{i}",
event_name="page_view", occurred_at=day + timedelta(seconds=i), path="/")
def test_refresh_daily_two_days(db):
site = Site.objects.create(name="s", domains=["a.com"])
_mk(site, "v1", "s1", YESTERDAY, 3) # v1 昨天 3 事件
_mk(site, "v1", "s2", NOW, 2, stay=8000) # v1 今天 2 事件
_mk(site, "v2", "s3", NOW, 4) # v2 今天 4 事件
y = refresh_daily(site, YESTERDAY.date())
t = refresh_daily(site, NOW.date())
# new_visitors 口径 = first_seen_at 落入当日。测试里 v1 虽有昨日事件,但访客记录是测试运行时(今天)建档的
# (auto_now_add),故昨天 new=0、今天 new=2(v1+v2)——按 first_seen_at 真实语义断言
assert (y.pv, y.uv, y.sessions, y.new_visitors) == (3, 1, 1, 0)
assert (t.pv, t.uv, t.sessions, t.new_visitors) == (6, 2, 2, 2) # 今天:pv=6 uv=2(v1+v2) sessions=2 new=2(v1+v2)