Coverage for app / backend / src / tests / test_metrics.py: 97%

51 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-05-19 04:11 +0000

1from datetime import timedelta 

2 

3import pytest 

4from google.protobuf import empty_pb2 

5from sqlalchemy import update 

6 

7from couchers.db import session_scope 

8from couchers.materialized_views import refresh_materialized_views 

9from couchers.metrics import ( 

10 _set_hacky_labeled_gauges_funcs, 

11 active_users_by_recency_gauge, 

12 users_per_community_gauge, 

13) 

14from couchers.models import User 

15from couchers.utils import now 

16from tests.fixtures.db import generate_user 

17from tests.test_communities import create_community 

18 

19 

20@pytest.fixture(autouse=True) 

21def _(testconfig): 

22 pass 

23 

24 

25def _populate(gauge): 

26 for registered_gauge, f in _set_hacky_labeled_gauges_funcs: 26 ↛ 30line 26 didn't jump to line 30 because the loop on line 26 didn't complete

27 if registered_gauge is gauge: 

28 f(registered_gauge) 

29 return 

30 raise AssertionError("gauge is not a registered labeled gauge") 

31 

32 

33def _sample_values(gauge): 

34 return { 

35 sample.labels[gauge._labelnames[0]]: sample.value for metric in gauge.collect() for sample in metric.samples 

36 } 

37 

38 

39def test_users_per_community_gauge(db): 

40 user1, _ = generate_user() 

41 user2, _ = generate_user() 

42 user3, _ = generate_user() 

43 

44 with session_scope() as session: 

45 world = create_community(session, 0, 100, "World", [user1], [], None) 

46 macroregion = create_community(session, 0, 50, "Macroregion", [user2], [], world) 

47 region = create_community(session, 0, 25, "Region", [user3], [user1], macroregion) 

48 # subregion is below the region level and must be excluded 

49 create_community(session, 0, 10, "Subregion", [user2], [user3], region) 

50 

51 # the gauge reads from the cluster_subscription_counts materialized view 

52 refresh_materialized_views(empty_pb2.Empty()) 

53 

54 _populate(users_per_community_gauge) 

55 values = _sample_values(users_per_community_gauge) 

56 

57 assert values["World"] == 1 

58 assert values["Macroregion"] == 1 

59 assert values["Region"] == 2 

60 assert "Subregion" not in values 

61 

62 

63def test_active_users_by_recency_gauge(db): 

64 ages = { 

65 "<1d": timedelta(hours=2), 

66 "1d-1w": timedelta(days=3), 

67 "1w-1m": timedelta(days=14), 

68 "1m-6m": timedelta(days=60), 

69 "6m-12m": timedelta(days=250), 

70 "12m-24m": timedelta(days=500), 

71 "24m+": timedelta(days=800), 

72 } 

73 user_ids_by_bucket = {} 

74 for bucket in ages: 

75 user, _ = generate_user() 

76 user_ids_by_bucket[bucket] = user.id 

77 

78 with session_scope() as session: 

79 for bucket, age in ages.items(): 

80 session.execute(update(User).where(User.id == user_ids_by_bucket[bucket]).values(last_active=now() - age)) 

81 

82 _populate(active_users_by_recency_gauge) 

83 values = _sample_values(active_users_by_recency_gauge) 

84 

85 for bucket in ages: 

86 assert values[bucket] == 1