Skip to content

Commit

Permalink
Add new integration and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aliu39 committed Dec 4, 2024
1 parent 3e43a91 commit 3652ce3
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
18 changes: 18 additions & 0 deletions sentry_sdk/integrations/featureflags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from sentry_sdk.flag_utils import flag_error_processor

import sentry_sdk
from sentry_sdk.integrations import Integration


class FeatureFlagsIntegration(Integration):
identifier = "featureflags"

@staticmethod
def setup_once():
scope = sentry_sdk.get_current_scope()
scope.add_error_processor(flag_error_processor)

@staticmethod
def set_flag(flag: str, result: bool):
flags = sentry_sdk.get_current_scope().flags
flags.set(flag, result)
Empty file.
73 changes: 73 additions & 0 deletions tests/integrations/featureflags/test_featureflags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import asyncio
import concurrent.futures as cf

import sentry_sdk
from sentry_sdk.integrations.featureflags import FeatureFlagsIntegration


def test_featureflags_integration(sentry_init):
sentry_init(integrations=[FeatureFlagsIntegration()])
flags_integration = sentry_sdk.get_client().get_integration(FeatureFlagsIntegration)

flags_integration.set_flag("hello", False)
flags_integration.set_flag("world", True)
flags_integration.set_flag("other", False)

assert sentry_sdk.get_current_scope().flags.get() == [
{"flag": "hello", "result": False},
{"flag": "world", "result": True},
{"flag": "other", "result": False},
]


def test_featureflags_integration_threaded(sentry_init):
sentry_init(integrations=[FeatureFlagsIntegration()])
flags_integration = sentry_sdk.get_client().get_integration(FeatureFlagsIntegration)

def task(flag_key):
# Creates a new isolation scope for the thread.
# This means the evaluations in each task are captured separately.
with sentry_sdk.isolation_scope():
flags_integration.set_flag(flag_key, False)
return sentry_sdk.get_current_scope().flags.get()

# Capture an eval before we split isolation scopes.
flags_integration.set_flag("hello", False)

with cf.ThreadPoolExecutor(max_workers=2) as pool:
results = list(pool.map(task, ["world", "other"]))

assert results[0] == [
{"flag": "hello", "result": False},
{"flag": "world", "result": False},
]
assert results[1] == [
{"flag": "hello", "result": False},
{"flag": "other", "result": False},
]


def test_featureflags_integration_asyncio(sentry_init):
"""Assert concurrently evaluated flags do not pollute one another."""
sentry_init(integrations=[FeatureFlagsIntegration()])
flags_integration = sentry_sdk.get_client().get_integration(FeatureFlagsIntegration)

async def task(flag_key):
with sentry_sdk.isolation_scope():
flags_integration.set_flag(flag_key, False)
return sentry_sdk.get_current_scope().flags.get()

async def runner():
return asyncio.gather(task("world"), task("other"))

flags_integration.set_flag("hello", False)

results = asyncio.run(runner()).result()
assert results[0] == [
{"flag": "hello", "result": False},
{"flag": "world", "result": False},
]
assert results[1] == [
{"flag": "hello", "result": False},
{"flag": "other", "result": False},
]

0 comments on commit 3652ce3

Please sign in to comment.