Skip to content

Commit 2a443b9

Browse files
committed
Patch class method instead of instance, so passing in client is not needed. Ref tests back to 1 file
1 parent 2ef2f7d commit 2a443b9

File tree

5 files changed

+107
-134
lines changed

5 files changed

+107
-134
lines changed

sentry_sdk/integrations/unleash.py

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,31 @@
11
from functools import wraps
2+
from typing import TYPE_CHECKING
23

34
import sentry_sdk
45
from sentry_sdk.flag_utils import flag_error_processor
5-
from sentry_sdk.integrations import Integration, DidNotEnable
6-
7-
from typing import TYPE_CHECKING
6+
from sentry_sdk.integrations import Integration
87

8+
from UnleashClient import UnleashClient
99

1010
if TYPE_CHECKING:
11-
from typing import Optional, Any
12-
from UnleashClient import UnleashClient
11+
from typing import Any
1312

1413

1514
class UnleashIntegration(Integration):
1615
identifier = "unleash"
17-
_unleash_client = None # type: Optional[UnleashClient]
18-
19-
def __init__(self, unleash_client):
20-
# type: (UnleashClient) -> None
21-
self.__class__._unleash_client = unleash_client
2216

2317
@staticmethod
2418
def setup_once():
2519
# type: () -> None
2620

2721
# Wrap and patch evaluation functions
28-
client = UnleashIntegration._unleash_client
29-
if not client:
30-
raise DidNotEnable("Error finding UnleashClient instance.")
31-
32-
# Instance methods (self is excluded)
33-
old_is_enabled = client.is_enabled
34-
old_get_variant = client.get_variant
22+
old_is_enabled = UnleashClient.is_enabled
23+
old_get_variant = UnleashClient.get_variant
3524

3625
@wraps(old_is_enabled)
37-
def sentry_is_enabled(feature, *a, **kw):
38-
# type: (str, *Any, **Any) -> Any
39-
enabled = old_is_enabled(feature, *a, **kw)
26+
def sentry_is_enabled(self, feature, *a, **kw):
27+
# type: (UnleashClient, str, *Any, **Any) -> Any
28+
enabled = old_is_enabled(self, feature, *a, **kw)
4029

4130
# We have no way of knowing what type of feature this is. Have to treat it as
4231
# boolean flag. TODO: Unless we fetch a list of non-bool flags on startup..
@@ -46,9 +35,9 @@ def sentry_is_enabled(feature, *a, **kw):
4635
return enabled
4736

4837
@wraps(old_get_variant)
49-
def sentry_get_variant(feature, *a, **kw):
50-
# type: (str, *Any, **Any) -> Any
51-
variant = old_get_variant(feature, *a, **kw)
38+
def sentry_get_variant(self, feature, *a, **kw):
39+
# type: (UnleashClient, str, *Any, **Any) -> Any
40+
variant = old_get_variant(self, feature, *a, **kw)
5241
enabled = variant.get("enabled", False)
5342
payload_type = variant.get("payload", {}).get("type")
5443

@@ -58,8 +47,8 @@ def sentry_get_variant(feature, *a, **kw):
5847

5948
return variant
6049

61-
client.is_enabled = sentry_is_enabled # type: ignore
62-
client.get_variant = sentry_get_variant # type: ignore
50+
UnleashClient.is_enabled = sentry_is_enabled # type: ignore
51+
UnleashClient.get_variant = sentry_get_variant # type: ignore
6352

6453
# Error processor
6554
scope = sentry_sdk.get_current_scope()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class MockUnleashClient:
2+
3+
def __init__(self, *a, **kw):
4+
self.features = {
5+
"hello": True,
6+
"world": False,
7+
}
8+
9+
self.feature_to_variant = {
10+
"string_feature": {
11+
"name": "variant1",
12+
"enabled": True,
13+
"payload": {"type": "string", "value": "val1"},
14+
},
15+
"json_feature": {
16+
"name": "variant1",
17+
"enabled": True,
18+
"payload": {"type": "json", "value": '{"key1": 0.53}'},
19+
},
20+
"number_feature": {
21+
"name": "variant1",
22+
"enabled": True,
23+
"payload": {"type": "number", "value": "134.5"},
24+
},
25+
"csv_feature": {
26+
"name": "variant1",
27+
"enabled": True,
28+
"payload": {"type": "csv", "value": "abc 123\ncsbq 94"},
29+
},
30+
"toggle_feature": {"name": "variant1", "enabled": True},
31+
}
32+
33+
self.disabled_variant = {"name": "disabled", "enabled": False}
34+
35+
def is_enabled(self, feature, *a, **kw):
36+
return self.features.get(feature, False)
37+
38+
def get_variant(self, feature, *a, **kw):
39+
return self.feature_to_variant.get(feature, self.disabled_variant)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from unittest.mock import patch
2+
3+
import sentry_sdk
4+
from sentry_sdk.integrations.unleash import UnleashIntegration
5+
from tests.integrations.unleash import MockUnleashClient
6+
7+
8+
@patch("sentry_sdk.integrations.unleash.UnleashClient", MockUnleashClient)
9+
def test_is_enabled(sentry_init, capture_events, uninstall_integration):
10+
mock_unleash_client = MockUnleashClient()
11+
12+
uninstall_integration(UnleashIntegration.identifier)
13+
sentry_init(integrations=[UnleashIntegration()])
14+
15+
mock_unleash_client.is_enabled("hello")
16+
mock_unleash_client.is_enabled("world")
17+
mock_unleash_client.is_enabled("other")
18+
19+
events = capture_events()
20+
sentry_sdk.capture_exception(Exception("something wrong!"))
21+
22+
assert len(events) == 1
23+
assert events[0]["contexts"]["flags"] == {
24+
"values": [
25+
{"flag": "hello", "result": True},
26+
{"flag": "world", "result": False},
27+
{"flag": "other", "result": False},
28+
]
29+
}
30+
31+
32+
@patch("sentry_sdk.integrations.unleash.UnleashClient", MockUnleashClient)
33+
def test_get_variant(sentry_init, capture_events, uninstall_integration):
34+
mock_unleash_client = MockUnleashClient()
35+
uninstall_integration(UnleashIntegration.identifier)
36+
sentry_init(integrations=[UnleashIntegration()])
37+
38+
mock_unleash_client.get_variant("toggle_feature")
39+
mock_unleash_client.get_variant("string_feature")
40+
mock_unleash_client.get_variant("json_feature")
41+
mock_unleash_client.get_variant("csv_feature")
42+
mock_unleash_client.get_variant("number_feature")
43+
mock_unleash_client.get_variant("unknown_feature")
44+
45+
events = capture_events()
46+
sentry_sdk.capture_exception(Exception("something wrong!"))
47+
48+
assert len(events) == 1
49+
assert events[0]["contexts"]["flags"] == {
50+
"values": [
51+
{"flag": "toggle_feature", "result": True},
52+
{"flag": "unknown_feature", "result": False},
53+
]
54+
}

tests/integrations/unleash/test_unleash_get_variant.py

Lines changed: 0 additions & 66 deletions
This file was deleted.

tests/integrations/unleash/test_unleash_is_enabled.py

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)