Skip to content

Commit b44cf42

Browse files
fix: metrics endpoint identity overrides (#6159)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 1438418 commit b44cf42

5 files changed

Lines changed: 31 additions & 123 deletions

File tree

api/environments/dynamodb/wrappers/identity_wrapper.py

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -199,34 +199,3 @@ def get_segment_ids(
199199
return [segment.id for segment in segments]
200200

201201
return []
202-
203-
def get_identity_overrides_count(self, environment_api_key: str) -> int:
204-
return sum(
205-
len({f["feature_id"] for f in identity["identity_features"]})
206-
for identity in self.iter_all_items_paginated(
207-
environment_api_key=environment_api_key,
208-
overrides_only=True,
209-
)
210-
)
211-
212-
def get_identity_override_feature_counts(
213-
self, environment_api_key: str
214-
) -> dict[int, int]:
215-
feature_to_identity_count: dict[int, int] = {}
216-
217-
for identity in self.iter_all_items_paginated(
218-
environment_api_key=environment_api_key,
219-
overrides_only=True,
220-
):
221-
unique_feature_ids: set[int] = set()
222-
223-
for feature_override in identity.get("identity_features", []):
224-
feature_id = feature_override.get("feature", {}).get("id", 0)
225-
unique_feature_ids.add(feature_id)
226-
227-
for feature_id in unique_feature_ids:
228-
feature_to_identity_count[feature_id] = (
229-
feature_to_identity_count.get(feature_id, 0) + 1
230-
)
231-
232-
return feature_to_identity_count

api/environments/models.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,11 +479,12 @@ def get_scheduled_metrics_queryset(self) -> QuerySet[FeatureState]:
479479
& Q(change_sets__live_from__gt=timezone.now())
480480
)
481481
)
482-
483-
change_requests: QuerySet["ChangeRequest"] = qs.filter(
484-
id__in=qs.filter(scheduled_q).values_list("id", flat=True)
482+
ids = qs.filter(scheduled_q).values_list("id", flat=True)
483+
unique_ids = list(set(ids))
484+
change_requests_qs: QuerySet["ChangeRequest"] = ChangeRequest.objects.filter(
485+
id__in=unique_ids
485486
)
486-
return change_requests
487+
return change_requests_qs
487488

488489
@staticmethod
489490
def is_bad_key(environment_key: str) -> bool:

api/metrics/metrics_service.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.db import models
66
from django.db.models import Q
77

8-
from edge_api.identities.models import EdgeIdentity
8+
from edge_api.identities import edge_identity_service
99
from environments.models import Environment
1010
from features.models import Feature
1111
from metrics.constants import DEFAULT_METRIC_DEFINITIONS, WORKFLOW_METRIC_DEFINITIONS
@@ -83,26 +83,26 @@ def _get_identity_metrics(self) -> dict[EnvMetricsName, Callable[[], int]]:
8383
}
8484

8585
def _get_active_identity_edge_overrides_count(self) -> int:
86-
override_feature_id_counts = (
87-
EdgeIdentity.dynamo_wrapper.get_identity_override_feature_counts(
88-
self.environment.api_key
89-
)
90-
)
91-
92-
valid_feature_ids = set(
86+
environment_feature_ids = set(
9387
Feature.objects.filter(
9488
project=self.environment.project,
9589
is_archived=False,
9690
deleted_at__isnull=True,
9791
).values_list("id", flat=True)
9892
)
9993

100-
return sum(
101-
count
102-
for feature_id, count in override_feature_id_counts.items()
103-
if feature_id in valid_feature_ids
94+
all_overrides = edge_identity_service.get_edge_identity_overrides(
95+
environment_id=self.environment.id,
96+
feature_id=None,
10497
)
10598

99+
count = 0
100+
for override in all_overrides:
101+
if override.feature_state.feature.id in environment_feature_ids:
102+
count += 1
103+
104+
return count
105+
106106
def _get_feature_metrics(
107107
self,
108108
) -> dict[EnvMetricsName, Callable[[], int]]:

api/tests/unit/environments/dynamodb/wrappers/test_unit_dynamodb_identity_wrapper.py

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -601,74 +601,3 @@ def test_delete_all_identities__deletes_all_identities_documents_from_dynamodb(
601601
# Then
602602
assert flagsmith_identities_table.scan()["Count"] == 1
603603
assert flagsmith_identities_table.scan()["Items"][0] == identity_three
604-
605-
606-
@pytest.mark.parametrize(
607-
"identity_features, expected_counts",
608-
[
609-
(
610-
[[1, 2, 3], [99], []],
611-
{1: 1, 2: 1, 3: 1, 99: 1},
612-
),
613-
(
614-
[[1, 2, 3], [99], [1, 2, 3, 99]],
615-
{1: 2, 2: 2, 3: 2, 99: 2},
616-
),
617-
(
618-
[[], [], []],
619-
{},
620-
),
621-
(
622-
[[], [1, 2, 3], []],
623-
{1: 1, 2: 1, 3: 1},
624-
),
625-
(
626-
[[4], [4, 25, 18, 19, 85, 100], [4]],
627-
{4: 3, 25: 1, 18: 1, 19: 1, 85: 1, 100: 1},
628-
),
629-
],
630-
)
631-
def test_get_identity_override_feature_counts_dynamo_returns_correct_total(
632-
flagsmith_identities_table: Table,
633-
dynamodb_identity_wrapper: DynamoIdentityWrapper,
634-
identity_features: list[list[int]],
635-
expected_counts: dict[int, int],
636-
) -> None:
637-
environment_api_key = "env_test"
638-
639-
identity_one = {
640-
"composite_key": f"{environment_api_key}_identity1",
641-
"environment_api_key": environment_api_key,
642-
"identifier": "user1",
643-
"identity_features": [
644-
{"feature": {"id": feature_id}} for feature_id in identity_features[0]
645-
],
646-
}
647-
648-
identity_two = {
649-
"composite_key": f"{environment_api_key}_identity2",
650-
"environment_api_key": environment_api_key,
651-
"identifier": "user2",
652-
"identity_features": [
653-
{"feature": {"id": feature_id}} for feature_id in identity_features[1]
654-
],
655-
}
656-
657-
identity_three = {
658-
"composite_key": f"{environment_api_key}_identity3",
659-
"environment_api_key": environment_api_key,
660-
"identifier": "user3",
661-
"identity_features": [
662-
{"feature": {"id": feature_id}} for feature_id in identity_features[2]
663-
],
664-
}
665-
666-
flagsmith_identities_table.put_item(Item=identity_one)
667-
flagsmith_identities_table.put_item(Item=identity_two)
668-
flagsmith_identities_table.put_item(Item=identity_three)
669-
670-
result = dynamodb_identity_wrapper.get_identity_override_feature_counts(
671-
environment_api_key
672-
)
673-
674-
assert result == expected_counts

api/tests/unit/metrics/test_unit_metrics_service.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def test_environment_metrics_service_builds_expected_metrics(
7272

7373

7474
@pytest.mark.parametrize("uses_dynamo, expected_value", [(True, 99), (False, 1)])
75+
@pytest.mark.django_db
7576
def test_dynamo_identity_metric_used(
7677
monkeypatch: pytest.MonkeyPatch,
7778
environment: Environment,
@@ -83,8 +84,7 @@ def test_dynamo_identity_metric_used(
8384
monkeypatch.setattr(
8485
environment, "get_segment_metrics_queryset", lambda: MagicMock(count=lambda: 1)
8586
)
86-
Feature.objects.create(
87-
id=10,
87+
feature = Feature.objects.create(
8888
project=environment.project,
8989
name="feature-10",
9090
is_archived=False,
@@ -97,14 +97,20 @@ def test_dynamo_identity_metric_used(
9797
lambda: MagicMock(count=identity_count_mock),
9898
)
9999

100-
dynamo_mock = MagicMock(return_value={10: 99})
100+
mock_override = MagicMock()
101+
mock_override.feature_state.feature.id = feature.id
102+
mock_overrides = [mock_override] * 99
103+
104+
dynamo_mock = MagicMock(return_value=mock_overrides)
101105
monkeypatch.setattr(
102-
"edge_api.identities.models.EdgeIdentity.dynamo_wrapper.get_identity_override_feature_counts",
106+
"edge_api.identities.edge_identity_service.get_edge_identity_overrides",
103107
dynamo_mock,
104108
)
109+
105110
# When
106111
metrics_service = EnvironmentMetricsService(environment)
107112
metrics = metrics_service.get_metrics_payload()
113+
108114
# Then
109115
assert metrics_service.uses_dynamo == uses_dynamo
110116
assert any(
@@ -114,7 +120,10 @@ def test_dynamo_identity_metric_used(
114120
)
115121

116122
if uses_dynamo:
117-
dynamo_mock.assert_called_once()
123+
dynamo_mock.assert_called_once_with(
124+
environment_id=environment.id,
125+
feature_id=None,
126+
)
118127
identity_count_mock.assert_not_called()
119128
else:
120129
identity_count_mock.assert_called_once()

0 commit comments

Comments
 (0)