Skip to content

Commit

Permalink
feat: Inline contexts for all evaluation events (#245)
Browse files Browse the repository at this point in the history
  • Loading branch information
keelerm84 committed Mar 13, 2024
1 parent c7b42a2 commit 8b6f37b
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 13 deletions.
3 changes: 2 additions & 1 deletion contract-tests/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ def status():
'tags',
'migrations',
'event-sampling',
'polling-gzip'
'polling-gzip',
'inline-context'
]
}
return (json.dumps(body), 200, {'Content-type': 'application/json'})
Expand Down
2 changes: 1 addition & 1 deletion ldclient/impl/events/event_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def make_output_events(self, events: List[Any], summary: EventSummary):
def make_output_event(self, e: Any):
if isinstance(e, EventInputEvaluation):
out = self._base_eval_props(e, 'feature')
out['contextKeys'] = self._context_keys(e.context)
out['context'] = self._process_context(e.context)
return out
elif isinstance(e, DebugEvent):
out = self._base_eval_props(e.original_input, 'debug')
Expand Down
19 changes: 8 additions & 11 deletions testing/impl/events/test_event_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from ldclient.migrations.tracker import MigrationOpEvent
from ldclient.impl.events.types import EventInput, EventInputCustom, EventInputEvaluation, EventInputIdentify
from ldclient.impl.util import timedelta_millis
from ldclient.impl.events.event_context_formatter import EventContextFormatter

from testing.builders import *
from testing.proxy_test_util import do_proxy_tests
Expand All @@ -23,12 +24,6 @@

default_config = Config("fake_sdk_key")
context = Context.builder('userkey').name('Red').build()
filtered_context = context.to_dict() # TODO: implement attribute redaction
filtered_context = {
'kind': 'user',
'key': 'userkey',
'_meta': {'redactedAttributes': ['name']}
}
flag = FlagBuilder('flagkey').version(2).build()
flag_with_0_sampling_ratio = FlagBuilder('flagkey').version(3).sampling_ratio(0).build()
flag_excluded_from_summaries = FlagBuilder('flagkey').version(4).exclude_from_summaries(True).build()
Expand Down Expand Up @@ -233,12 +228,13 @@ def test_identify_event_is_queued():

def test_context_is_filtered_in_identify_event():
with DefaultTestProcessor(all_attributes_private = True) as ep:
formatter = EventContextFormatter(True, [])
e = EventInputIdentify(timestamp, context)
ep.send_event(e)

output = flush_and_get_events(ep)
assert len(output) == 1
check_identify_event(output[0], e, filtered_context)
check_identify_event(output[0], e, formatter.format_context(context))

def test_individual_feature_event_is_queued_with_index_event():
with DefaultTestProcessor() as ep:
Expand Down Expand Up @@ -275,13 +271,14 @@ def test_exclude_can_keep_feature_event_from_summary():

def test_context_is_filtered_in_index_event():
with DefaultTestProcessor(all_attributes_private = True) as ep:
formatter = EventContextFormatter(True, [])
e = EventInputEvaluation(timestamp, context, flag.key, flag, 1, 'value', None, 'default', None, True)
ep.send_event(e)

output = flush_and_get_events(ep)
assert len(output) == 3
check_index_event(output[0], e, filtered_context)
check_feature_event(output[1], e)
check_index_event(output[0], e, formatter.format_context(context))
check_feature_event(output[1], e, formatter.format_context(context))
check_summary_event(output[2])

def test_two_events_for_same_context_only_produce_one_index_event():
Expand Down Expand Up @@ -682,15 +679,15 @@ def check_index_event(data, source: EventInput, context_json: Optional[dict] = N
assert data['creationDate'] == source.timestamp
assert data['context'] == (source.context.to_dict() if context_json is None else context_json)

def check_feature_event(data, source: EventInputEvaluation):
def check_feature_event(data, source: EventInputEvaluation, context_json: Optional[dict] = None):
assert data['kind'] == 'feature'
assert data['creationDate'] == source.timestamp
assert data['key'] == source.key
assert data.get('version') == None if source.flag is None else source.flag.version
assert data.get('variation') == source.variation
assert data.get('value') == source.value
assert data.get('default') == source.default_value
assert data['contextKeys'] == make_context_keys(source.context)
assert data['context'] == (source.context.to_dict() if context_json is None else context_json)
assert data.get('prereq_of') == None if source.prereq_of is None else source.prereq_of.key


Expand Down

0 comments on commit 8b6f37b

Please sign in to comment.