def test_get_package_version_metrics_intervals(dao: Dao, channel, db, package_version, interval): now = datetime.datetime(2020, 10, 1, 10, 1, 10) dao.incr_download_count(channel.name, package_version.filename, package_version.platform, timestamp=now) metrics = dao.get_package_version_metrics(package_version.id, interval, "download") timestamp_interval = round_timestamp(now, interval) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [(timestamp_interval, 1)] end = timestamp_interval.replace(year=2021) metrics = dao.get_package_version_metrics( package_version.id, interval, "download", start=timestamp_interval, end=end, fill_zeros=True, ) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict[0] == (timestamp_interval, 1) assert metrics_dict[-1] == (end, 0)
def test_synchronize_metrics_without_mirrors(public_channel, package_version, dao: Dao): session = Mock() synchronize_metrics_from_mirrors(public_channel.name, dao, session) metrics = dao.get_package_version_metrics(package_version.id, IntervalType.hour, "download") assert not metrics session.get.assert_not_called()
def get_package_version_metrics( platform: str, filename: str, package_name: str, channel_name: str, fill_zeros: bool = False, period: IntervalType = IntervalType.day, metric_name: str = "download", start: Optional[datetime] = None, end: Optional[datetime] = None, package: db_models.Package = Depends(get_package_or_fail), dao: Dao = Depends(get_dao), ): version = dao.get_package_version_by_filename(channel_name, package_name, filename, platform) if not version: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"package version {platform}/{filename} not found", ) series = dao.get_package_version_metrics(version.id, period, metric_name, start=start, end=end, fill_zeros=fill_zeros) total = sum(s.count for s in series) return { "server_timestamp": datetime.utcnow(), "period": period, "metric_name": metric_name, "total": total, "series": series, }
def test_synchronize_metrics_with_mirrors(public_channel, package_version, channel_mirror, dao: Dao): timestamp = datetime(2020, 10, 1, 5, 0) first_sync_time = timestamp - timedelta(days=1) sync_time = timestamp + timedelta(hours=1) session = Mock() session.get.return_value.json.return_value = { "server_timestamp": first_sync_time.isoformat(), "packages": {}, } session.get.return_value.status_code = 200 synchronize_metrics_from_mirrors(public_channel.name, dao, session, now=first_sync_time) metrics = dao.get_package_version_metrics(package_version.id, IntervalType.hour, "download") assert not metrics session.get.assert_called_with( "http://mirror_server/metrics/channels/my-mirror" f"?period=H&end={first_sync_time.isoformat()}") session.reset_mock() session.get.return_value.json.return_value = { "server_timestamp": sync_time.isoformat(), "packages": { f"{package_version.platform}/{package_version.filename}": { "series": [ { "timestamp": timestamp.isoformat(), "count": 2 }, ] } }, } synchronize_metrics_from_mirrors(public_channel.name, dao, session, sync_time) for p in IntervalType: metrics = dao.get_package_version_metrics(package_version.id, p, "download") assert len(metrics) == 1 assert metrics[0].count == 2 session.get.assert_called_with( "http://mirror_server/metrics/channels/my-mirror" f"?period=H&start={first_sync_time.isoformat()}&end={sync_time.isoformat()}" ) session.reset_mock() hour = timedelta(hours=1) session.get.return_value.json.return_value = { "server_timestamp": sync_time.replace(minute=5).isoformat(), "packages": { f"{package_version.platform}/{package_version.filename}": { "series": [ { "timestamp": (timestamp + hour).isoformat(), "count": 1, }, ] } }, } third_sync_time = sync_time + hour synchronize_metrics_from_mirrors(public_channel.name, dao, session, third_sync_time) session.get.assert_called_with( "http://mirror_server/metrics/channels/my-mirror" f"?period=H&start={sync_time.isoformat()}&end={third_sync_time.isoformat()}" ) metrics = dao.get_package_version_metrics(package_version.id, IntervalType.day, "download") assert len(metrics) == 1 assert metrics[0].count == 3
def test_get_package_version_metrics(dao: Dao, channel, db, package_version): now = datetime.datetime(2020, 10, 1, 10, 1, 10) dao.incr_download_count(channel.name, package_version.filename, package_version.platform, timestamp=now) metrics = dao.get_package_version_metrics(package_version.id, IntervalType.hour, "download") metrics_dict = [(m.timestamp, m.count) for m in metrics] timestamp = now.replace(minute=0, second=0) assert metrics_dict == [(timestamp, 1)] hour = datetime.timedelta(hours=1) day = datetime.timedelta(days=1) metrics = dao.get_package_version_metrics( package_version.id, IntervalType.hour, "download", start=now - hour, end=now + hour, ) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [(timestamp, 1)] metrics = dao.get_package_version_metrics( package_version.id, IntervalType.hour, "download", start=now - hour, end=now + hour, fill_zeros=True, ) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [ (timestamp - hour, 0), (timestamp, 1), (timestamp + hour, 0), ] # no start/end metrics = dao.get_package_version_metrics( package_version.id, IntervalType.hour, "download", start=now - hour, fill_zeros=True, ) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [ (timestamp - hour, 0), (timestamp, 1), ] metrics = dao.get_package_version_metrics( package_version.id, IntervalType.hour, "download", end=now + hour, fill_zeros=True, ) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [ (timestamp, 1), (timestamp + hour, 0), ] metrics = dao.get_package_version_metrics( package_version.id, IntervalType.hour, "download", fill_zeros=True, ) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [ (timestamp, 1), ] # day interval timestamp_day = timestamp.replace(hour=0) metrics = dao.get_package_version_metrics(package_version.id, IntervalType.day, "download") metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [(timestamp_day, 1)] metrics = dao.get_package_version_metrics( package_version.id, IntervalType.day, "download", start=now - day, end=now + day, fill_zeros=True, ) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [ (timestamp_day - day, 0), (timestamp_day, 1), (timestamp_day + day, 0), ] # two items dao.incr_download_count( channel.name, package_version.filename, package_version.platform, timestamp=now + datetime.timedelta(hours=2), ) metrics = dao.get_package_version_metrics( package_version.id, IntervalType.hour, "download", fill_zeros=True, ) metrics_dict = [(m.timestamp, m.count) for m in metrics] assert metrics_dict == [ (timestamp, 1), (timestamp + hour, 0), (timestamp + 2 * hour, 1), ]