22import sys
33from random import random
44from unittest import mock
5+ from UnleashClient import UnleashClient
56
67import pytest
78
89import sentry_sdk
910from sentry_sdk .integrations .unleash import UnleashIntegration
10- from tests .integrations .unleash .testutils import MockUnleashClient
11+ from tests .integrations .unleash .testutils import mock_unleash_client
1112
1213
1314def test_is_enabled (sentry_init , capture_events , uninstall_integration ):
14- client = MockUnleashClient ()
1515 uninstall_integration (UnleashIntegration )
16- sentry_init (integrations = [UnleashIntegration (client )]) # type: ignore
1716
18- client .is_enabled ("hello" )
19- client .is_enabled ("world" )
20- client .is_enabled ("other" )
17+ with mock_unleash_client ():
18+ client = UnleashClient ()
19+ sentry_init (integrations = [UnleashIntegration ()])
20+ client .is_enabled ("hello" )
21+ client .is_enabled ("world" )
22+ client .is_enabled ("other" )
2123
2224 events = capture_events ()
2325 sentry_sdk .capture_exception (Exception ("something wrong!" ))
@@ -33,16 +35,17 @@ def test_is_enabled(sentry_init, capture_events, uninstall_integration):
3335
3436
3537def test_get_variant (sentry_init , capture_events , uninstall_integration ):
36- client = MockUnleashClient ()
3738 uninstall_integration (UnleashIntegration )
38- sentry_init (integrations = [UnleashIntegration (client )]) # type: ignore
3939
40- client .get_variant ("no_payload_feature" )
41- client .get_variant ("string_feature" )
42- client .get_variant ("json_feature" )
43- client .get_variant ("csv_feature" )
44- client .get_variant ("number_feature" )
45- client .get_variant ("unknown_feature" )
40+ with mock_unleash_client ():
41+ client = UnleashClient ()
42+ sentry_init (integrations = [UnleashIntegration ()]) # type: ignore
43+ client .get_variant ("no_payload_feature" )
44+ client .get_variant ("string_feature" )
45+ client .get_variant ("json_feature" )
46+ client .get_variant ("csv_feature" )
47+ client .get_variant ("number_feature" )
48+ client .get_variant ("unknown_feature" )
4649
4750 events = capture_events ()
4851 sentry_sdk .capture_exception (Exception ("something wrong!" ))
@@ -61,25 +64,27 @@ def test_get_variant(sentry_init, capture_events, uninstall_integration):
6164
6265
6366def test_is_enabled_threaded (sentry_init , capture_events , uninstall_integration ):
64- client = MockUnleashClient ()
6567 uninstall_integration (UnleashIntegration )
66- sentry_init (integrations = [UnleashIntegration (client )]) # type: ignore
67- events = capture_events ()
6868
69- def task (flag_key ):
70- # Creates a new isolation scope for the thread.
71- # This means the evaluations in each task are captured separately.
72- with sentry_sdk .isolation_scope ():
73- client .is_enabled (flag_key )
74- # use a tag to identify to identify events later on
75- sentry_sdk .set_tag ("task_id" , flag_key )
76- sentry_sdk .capture_exception (Exception ("something wrong!" ))
69+ with mock_unleash_client ():
70+ client = UnleashClient ()
71+ sentry_init (integrations = [UnleashIntegration ()]) # type: ignore
72+ events = capture_events ()
73+
74+ def task (flag_key ):
75+ # Creates a new isolation scope for the thread.
76+ # This means the evaluations in each task are captured separately.
77+ with sentry_sdk .isolation_scope ():
78+ client .is_enabled (flag_key )
79+ # use a tag to identify to identify events later on
80+ sentry_sdk .set_tag ("task_id" , flag_key )
81+ sentry_sdk .capture_exception (Exception ("something wrong!" ))
7782
78- # Capture an eval before we split isolation scopes.
79- client .is_enabled ("hello" )
83+ # Capture an eval before we split isolation scopes.
84+ client .is_enabled ("hello" )
8085
81- with cf .ThreadPoolExecutor (max_workers = 2 ) as pool :
82- pool .map (task , ["world" , "other" ])
86+ with cf .ThreadPoolExecutor (max_workers = 2 ) as pool :
87+ pool .map (task , ["world" , "other" ])
8388
8489 # Capture error in original scope
8590 sentry_sdk .set_tag ("task_id" , "0" )
@@ -108,25 +113,27 @@ def task(flag_key):
108113
109114
110115def test_get_variant_threaded (sentry_init , capture_events , uninstall_integration ):
111- client = MockUnleashClient ()
112116 uninstall_integration (UnleashIntegration )
113- sentry_init (integrations = [UnleashIntegration (client )]) # type: ignore
114- events = capture_events ()
115117
116- def task (flag_key ):
117- # Creates a new isolation scope for the thread.
118- # This means the evaluations in each task are captured separately.
119- with sentry_sdk .isolation_scope ():
120- client .get_variant (flag_key )
121- # use a tag to identify to identify events later on
122- sentry_sdk .set_tag ("task_id" , flag_key )
123- sentry_sdk .capture_exception (Exception ("something wrong!" ))
118+ with mock_unleash_client ():
119+ client = UnleashClient ()
120+ sentry_init (integrations = [UnleashIntegration ()]) # type: ignore
121+ events = capture_events ()
124122
125- # Capture an eval before we split isolation scopes.
126- client .get_variant ("hello" )
123+ def task (flag_key ):
124+ # Creates a new isolation scope for the thread.
125+ # This means the evaluations in each task are captured separately.
126+ with sentry_sdk .isolation_scope ():
127+ client .get_variant (flag_key )
128+ # use a tag to identify to identify events later on
129+ sentry_sdk .set_tag ("task_id" , flag_key )
130+ sentry_sdk .capture_exception (Exception ("something wrong!" ))
127131
128- with cf .ThreadPoolExecutor (max_workers = 2 ) as pool :
129- pool .map (task , ["no_payload_feature" , "other" ])
132+ # Capture an eval before we split isolation scopes.
133+ client .get_variant ("hello" )
134+
135+ with cf .ThreadPoolExecutor (max_workers = 2 ) as pool :
136+ pool .map (task , ["no_payload_feature" , "other" ])
130137
131138 # Capture error in original scope
132139 sentry_sdk .set_tag ("task_id" , "0" )
@@ -157,26 +164,27 @@ def task(flag_key):
157164@pytest .mark .skipif (sys .version_info < (3 , 7 ), reason = "requires python3.7 or higher" )
158165def test_is_enabled_asyncio (sentry_init , capture_events , uninstall_integration ):
159166 asyncio = pytest .importorskip ("asyncio" )
160-
161- client = MockUnleashClient ()
162167 uninstall_integration (UnleashIntegration )
163- sentry_init (integrations = [UnleashIntegration (client )]) # type: ignore
164- events = capture_events ()
165168
166- async def task (flag_key ):
167- with sentry_sdk .isolation_scope ():
168- client .is_enabled (flag_key )
169- # use a tag to identify to identify events later on
170- sentry_sdk .set_tag ("task_id" , flag_key )
171- sentry_sdk .capture_exception (Exception ("something wrong!" ))
169+ with mock_unleash_client ():
170+ client = UnleashClient ()
171+ sentry_init (integrations = [UnleashIntegration ()]) # type: ignore
172+ events = capture_events ()
172173
173- async def runner ():
174- return asyncio .gather (task ("world" ), task ("other" ))
174+ async def task (flag_key ):
175+ with sentry_sdk .isolation_scope ():
176+ client .is_enabled (flag_key )
177+ # use a tag to identify to identify events later on
178+ sentry_sdk .set_tag ("task_id" , flag_key )
179+ sentry_sdk .capture_exception (Exception ("something wrong!" ))
175180
176- # Capture an eval before we split isolation scopes.
177- client . is_enabled ( "hello" )
181+ async def runner ():
182+ return asyncio . gather ( task ( "world" ), task ( "other" ) )
178183
179- asyncio .run (runner ())
184+ # Capture an eval before we split isolation scopes.
185+ client .is_enabled ("hello" )
186+
187+ asyncio .run (runner ())
180188
181189 # Capture error in original scope
182190 sentry_sdk .set_tag ("task_id" , "0" )
@@ -208,25 +216,27 @@ async def runner():
208216def test_get_variant_asyncio (sentry_init , capture_events , uninstall_integration ):
209217 asyncio = pytest .importorskip ("asyncio" )
210218
211- client = MockUnleashClient ()
212219 uninstall_integration (UnleashIntegration )
213- sentry_init (integrations = [UnleashIntegration (client )]) # type: ignore
214- events = capture_events ()
215220
216- async def task (flag_key ):
217- with sentry_sdk .isolation_scope ():
218- client .get_variant (flag_key )
219- # use a tag to identify to identify events later on
220- sentry_sdk .set_tag ("task_id" , flag_key )
221- sentry_sdk .capture_exception (Exception ("something wrong!" ))
221+ with mock_unleash_client ():
222+ client = UnleashClient ()
223+ sentry_init (integrations = [UnleashIntegration ()]) # type: ignore
224+ events = capture_events ()
225+
226+ async def task (flag_key ):
227+ with sentry_sdk .isolation_scope ():
228+ client .get_variant (flag_key )
229+ # use a tag to identify to identify events later on
230+ sentry_sdk .set_tag ("task_id" , flag_key )
231+ sentry_sdk .capture_exception (Exception ("something wrong!" ))
222232
223- async def runner ():
224- return asyncio .gather (task ("no_payload_feature" ), task ("other" ))
233+ async def runner ():
234+ return asyncio .gather (task ("no_payload_feature" ), task ("other" ))
225235
226- # Capture an eval before we split isolation scopes.
227- client .get_variant ("hello" )
236+ # Capture an eval before we split isolation scopes.
237+ client .get_variant ("hello" )
228238
229- asyncio .run (runner ())
239+ asyncio .run (runner ())
230240
231241 # Capture error in original scope
232242 sentry_sdk .set_tag ("task_id" , "0" )
@@ -254,39 +264,17 @@ async def runner():
254264 }
255265
256266
257- def test_client_isolation (sentry_init , capture_events , uninstall_integration ):
258- """
259- If the integration is tracking a single client, evaluations from other clients should not be
260- captured.
261- """
262- client = MockUnleashClient ()
263- uninstall_integration (UnleashIntegration )
264- sentry_init (integrations = [UnleashIntegration (client )]) # type: ignore
265-
266- other_client = MockUnleashClient ()
267-
268- other_client .is_enabled ("hello" )
269- other_client .is_enabled ("world" )
270- other_client .is_enabled ("other" )
271- other_client .get_variant ("no_payload_feature" )
272- other_client .get_variant ("json_feature" )
273-
274- events = capture_events ()
275- sentry_sdk .capture_exception (Exception ("something wrong!" ))
276-
277- assert len (events ) == 1
278- assert events [0 ]["contexts" ]["flags" ] == {"values" : []}
279-
280-
281267def test_wraps_original (sentry_init , uninstall_integration ):
282- client = MockUnleashClient ()
283- mock_is_enabled = mock .Mock (return_value = random () < 0.5 )
284- client .is_enabled = mock_is_enabled
285- mock_get_variant = mock .Mock (return_value = {"enabled" : random () < 0.5 })
286- client .get_variant = mock_get_variant
268+ with mock_unleash_client ():
269+ client = UnleashClient ()
287270
288- uninstall_integration (UnleashIntegration )
289- sentry_init (integrations = [UnleashIntegration (client )]) # type: ignore
271+ mock_is_enabled = mock .Mock (return_value = random () < 0.5 )
272+ mock_get_variant = mock .Mock (return_value = {"enabled" : random () < 0.5 })
273+ client .is_enabled = mock_is_enabled
274+ client .get_variant = mock_get_variant
275+
276+ uninstall_integration (UnleashIntegration )
277+ sentry_init (integrations = [UnleashIntegration ()]) # type: ignore
290278
291279 res = client .is_enabled ("test-flag" , "arg" , kwarg = 1 )
292280 assert res == mock_is_enabled .return_value
@@ -304,15 +292,17 @@ def test_wraps_original(sentry_init, uninstall_integration):
304292
305293
306294def test_wrapper_attributes (sentry_init , uninstall_integration ):
307- client = MockUnleashClient ()
308- original_is_enabled = client .is_enabled
309- original_get_variant = client .get_variant
295+ with mock_unleash_client ():
296+ client = UnleashClient () # <- Returns a MockUnleashClient
310297
311- uninstall_integration ( UnleashIntegration )
312- sentry_init ( integrations = [ UnleashIntegration ( client )]) # type: ignore
298+ original_is_enabled = client . is_enabled
299+ original_get_variant = client . get_variant
313300
314- assert client . is_enabled . __name__ == "is_enabled"
315- assert client . is_enabled . __qualname__ == original_is_enabled . __qualname__
301+ uninstall_integration ( UnleashIntegration )
302+ sentry_init ( integrations = [ UnleashIntegration ()]) # type: ignore
316303
317- assert client .get_variant .__name__ == "get_variant"
318- assert client .get_variant .__qualname__ == original_get_variant .__qualname__
304+ # Mock clients methods have not lost their qualified names after decoration.
305+ assert client .is_enabled .__name__ == "is_enabled"
306+ assert client .is_enabled .__qualname__ == original_is_enabled .__qualname__
307+ assert client .get_variant .__name__ == "get_variant"
308+ assert client .get_variant .__qualname__ == original_get_variant .__qualname__
0 commit comments