From 409f10ec53ae8c0bca55fb07ea1093055a4ac990 Mon Sep 17 00:00:00 2001 From: Bilal Al-Shahwany Date: Fri, 21 Aug 2026 12:51:55 -0700 Subject: [PATCH] updated constructors for SdkEvents and SSE classes --- setup.py | 2 +- splitio/client/factory.py | 183 +++++++------ splitio/events/__init__.py | 1 + splitio/events/events_emitter.py | 37 +++ splitio/push/models.py | 164 ++++++++++++ splitio/push/workers.py | 62 +++-- splitio/storage/inmemory.py | 8 +- tests/client/test_client.py | 315 +++++++++++++---------- tests/client/test_factory.py | 340 +++++++++++++------------ tests/client/test_manager.py | 4 +- tests/integration/test_client_e2e.py | 177 +++++++------ tests/push/test_split_worker.py | 92 ++++--- tests/sync/test_splits_synchronizer.py | 48 ++-- 13 files changed, 873 insertions(+), 560 deletions(-) create mode 100644 splitio/events/__init__.py create mode 100644 splitio/events/events_emitter.py create mode 100644 splitio/push/models.py diff --git a/setup.py b/setup.py index 92c17a92..099a6afd 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ 'docopt>=0.6.2', 'enum34;python_version<"3.4"', 'bloom-filter2>=2.0.0', - 'splitio_commons==1.1.0' + 'splitio_commons==2.0.0' ] with open(path.join(path.abspath(path.dirname(__file__)), 'splitio', 'version.py')) as f: diff --git a/splitio/client/factory.py b/splitio/client/factory.py index 27174743..c041af7d 100644 --- a/splitio/client/factory.py +++ b/splitio/client/factory.py @@ -19,14 +19,18 @@ from splitio_commons.events.events_task import EventsTask, EventsTaskAsync from splitio_commons.events.events_delivery import EventsDelivery from splitio_commons.models.fallback_config import FallbackTreatmentCalculator -from splitio_commons.models.notification import SdkInternalEventNotification from splitio_commons.models.events import SdkInternalEvent +from splitio.events.events_emitter import EventsEmitter # push from splitio_commons.push.manager import PushManager, PushManagerAsync from splitio_commons.push.processor import MessageProcessor, MessageProcessorAsync -from splitio_commons.push.parser import UpdateType from splitio.push.workers import SplitWorker, SplitWorkerAsync +from splitio_commons.push.update_event_type_util import UpdateEventTypeUtil, UpdateEventTypeUtilAsync +from splitio_commons.push.parser import SegmentChangeUpdate +from splitio_commons.push.workers import SegmentWorker, SegmentWorkerAsync +from splitio.push.models import EventUpdateType, SplitChangeUpdate, SplitKillUpdate, RBSChangeUpdate + # Storage from splitio.storage.inmemory import InMemorySplitStorage, InMemorySplitStorageAsync @@ -200,7 +204,7 @@ def __init__( # pylint: disable=too-many-arguments storages, labels_enabled, recorder, - internal_events_queue, + events_emitter, events_manager, sync_manager=None, sdk_ready_flag=None, @@ -240,7 +244,7 @@ def __init__( # pylint: disable=too-many-arguments _LOGGER.debug("Running in threading mode") self._sdk_internal_ready_flag = sdk_ready_flag self._fallback_treatment_calculator = fallback_treatment_calculator - self._internal_events_queue = internal_events_queue + self._events_emitter = events_emitter self._events_manager = events_manager self._start_status_updater() @@ -262,14 +266,14 @@ def _start_status_updater(self): ready_updater.start() else: self._status = Status.READY - self._internal_events_queue.put(SdkInternalEventNotification(SdkInternalEvent.SDK_READY, None)) + self._events_emitter.emit(SdkInternalEvent.SDK_READY, None) def _update_status_when_ready(self): """Wait until the sdk is ready and update the status.""" self._sdk_internal_ready_flag.wait() self._status = Status.READY self._sdk_ready_flag.set() - self._internal_events_queue.put(SdkInternalEventNotification(SdkInternalEvent.SDK_READY, None)) + self._events_emitter.emit(SdkInternalEvent.SDK_READY, None) self._telemetry_init_producer.record_ready_time(get_current_epoch_time_ms() - self._ready_time) redundant_factory_count, active_factory_count = _get_active_and_redundant_count() @@ -378,7 +382,7 @@ def __init__( # pylint: disable=too-many-arguments storages, labels_enabled, recorder, - internal_events_queue, + events_emitter, events_manager, sync_manager=None, telemetry_producer=None, @@ -415,7 +419,7 @@ def __init__( # pylint: disable=too-many-arguments self._telemetry_submitter = telemetry_submitter self._ready_time = get_current_epoch_time_ms() _LOGGER.debug("Running in asyncio mode") - self._internal_events_queue = internal_events_queue + self._events_emitter = events_emitter self._events_manager = events_manager self._manager_start_task = manager_start_task self._status = Status.NOT_INITIALIZED @@ -439,7 +443,7 @@ async def _update_status_when_ready_async(self): _LOGGER.debug(str(e)) self._status = Status.READY self._sdk_ready_flag.set() - await self._internal_events_queue.put(SdkInternalEventNotification(SdkInternalEvent.SDK_READY, None)) + await self._events_emitter.emit_async(SdkInternalEvent.SDK_READY, None) def manager(self): """ @@ -624,15 +628,17 @@ def _build_events_manager_classes(threading_mode): if threading_mode == ThreadingMode.ASYNC: internal_events_queue = asyncio.Queue() events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) + events_emitter = EventsEmitter(internal_events_queue) internal_events_task = EventsTaskAsync(events_manager.notify_internal_event, internal_events_queue) - return internal_events_queue, events_manager, internal_events_task + return events_emitter, events_manager, internal_events_task internal_events_queue = queue.Queue() events_manager = EventsManager(EventsManagerConfig(), EventsDelivery()) + events_emitter = EventsEmitter(internal_events_queue) internal_events_task = EventsTask(events_manager.notify_internal_event, internal_events_queue) - return internal_events_queue, events_manager, internal_events_task + return events_emitter, events_manager, internal_events_task -def _build_storage_classes(threading_mode, internal_events_queue, telemetry_runtime_producer, cfg, sdk_metadata=None, db_adapter=None, storage_prefix=None): +def _build_storage_classes(threading_mode, telemetry_runtime_producer, cfg, sdk_metadata=None, db_adapter=None, storage_prefix=None): if cfg['storageType'] == 'redis': cache_enabled = cfg.get('redisLocalCacheEnabled', False) cache_ttl = cfg.get('redisLocalCacheTTL', 5) @@ -676,17 +682,17 @@ def _build_storage_classes(threading_mode, internal_events_queue, telemetry_runt if threading_mode == ThreadingMode.ASYNC: return { - 'splits': InMemorySplitStorageAsync(internal_events_queue, cfg['flagSetsFilter'] if cfg['flagSetsFilter'] is not None else []), - 'segments': InMemorySegmentStorageAsync(internal_events_queue), - 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(internal_events_queue), + 'splits': InMemorySplitStorageAsync(cfg['flagSetsFilter'] if cfg['flagSetsFilter'] is not None else []), + 'segments': InMemorySegmentStorageAsync(), + 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(), 'impressions': InMemoryImpressionStorageAsync(cfg['impressionsQueueSize'], telemetry_runtime_producer), 'events': InMemoryEventStorageAsync(cfg['eventsQueueSize'], telemetry_runtime_producer), } return { - 'splits': InMemorySplitStorage(internal_events_queue, cfg['flagSetsFilter'] if cfg['flagSetsFilter'] is not None else []), - 'segments': InMemorySegmentStorage(internal_events_queue), - 'rule_based_segments': InMemoryRuleBasedSegmentStorage(internal_events_queue), + 'splits': InMemorySplitStorage(cfg['flagSetsFilter'] if cfg['flagSetsFilter'] is not None else []), + 'segments': InMemorySegmentStorage(), + 'rule_based_segments': InMemoryRuleBasedSegmentStorage(), 'impressions': InMemoryImpressionStorage(cfg['impressionsQueueSize'], telemetry_runtime_producer), 'events': InMemoryEventStorage(cfg['eventsQueueSize'], telemetry_runtime_producer), } @@ -703,7 +709,7 @@ def _build_engine_classes(impressions_mode, telemetry_runtime_producer): imp_manager = ImpressionsManager(imp_strategy, none_strategy, telemetry_runtime_producer) return imp_counter, imp_manager -def _build_synchronizer_classes(threading_mode, storages, apis, cfg, telemetry_submitter, unique_keys_tracker, imp_counter, sender_adapter): +def _build_synchronizer_classes(threading_mode, storages, apis, cfg, telemetry_submitter, unique_keys_tracker, imp_counter, sender_adapter, events_emitter): if cfg['storageType'] in ['redis', 'pluggable']: if threading_mode == ThreadingMode.ASYNC: return HarnessSynchronizers(None, None, None, None, @@ -723,7 +729,7 @@ def _build_synchronizer_classes(threading_mode, storages, apis, cfg, telemetry_s if threading_mode == ThreadingMode.ASYNC: return HarnessSynchronizers( SplitSynchronizerAsync(apis['splits'], storages['splits'], storages['rule_based_segments']), - SegmentSynchronizerAsync(apis['segments'], storages['splits'], storages['segments'], storages['rule_based_segments']), + SegmentSynchronizerAsync(apis['segments'], storages['splits'], storages['segments'], storages['rule_based_segments'], events_emitter), ImpressionSynchronizerAsync(apis['impressions'], storages['impressions'], cfg['impressionsBulkSize']), EventSynchronizerAsync(apis['events'], storages['events'], cfg['eventsBulkSize']), @@ -735,7 +741,7 @@ def _build_synchronizer_classes(threading_mode, storages, apis, cfg, telemetry_s return HarnessSynchronizers( SplitSynchronizer(apis['splits'], storages['splits'], storages['rule_based_segments']), - SegmentSynchronizer(apis['segments'], storages['splits'], storages['segments'], storages['rule_based_segments']), + SegmentSynchronizer(apis['segments'], storages['splits'], storages['segments'], storages['rule_based_segments'], events_emitter), ImpressionSynchronizer(apis['impressions'], storages['impressions'], cfg['impressionsBulkSize']), EventSynchronizer(apis['events'], storages['events'], cfg['eventsBulkSize']), @@ -804,34 +810,48 @@ def _build_sync_tasks(threading_mode, synchronizers, cfg, internal_events_task): ClearFilterSyncTask(synchronizers.clear_filter_sync.clear_all), internal_events_task ) - -def _build_push_classes(threading_mode, synchronizer, cfg, telemetry_runtime_producer, apis, sdk_metadata, streaming_api_base_url, api_key): + +async def _build_push_classes_async(synchronizer, cfg, telemetry_runtime_producer, apis, sdk_metadata, streaming_api_base_url, api_key, events_emitter): push_queue = None push_manager = None if cfg['streamingEnabled']: - if threading_mode == ThreadingMode.ASYNC: - push_queue = asyncio.Queue() - split_worker = SplitWorkerAsync(synchronizer.synchronize_definitions, synchronizer.synchronize_segment, asyncio.Queue(), synchronizer.definition_sync, synchronizer.definition_sync.definition_storage, synchronizer.segment_storage, telemetry_runtime_producer, synchronizer.definition_sync.rule_based_segment_storage) - split_handlers = { - UpdateType.SPLIT_UPDATE: split_worker.handle_feature_flag_update, - UpdateType.SPLIT_KILL: split_worker.handle_feature_flag_kill, - UpdateType.RB_SEGMENT_UPDATE: split_worker.handle_feature_flag_update - } - auth_synchronizer = AuthSynchronizerAsync(apis['auth'], telemetry_runtime_producer, push_queue) - processor = MessageProcessorAsync(synchronizer, split_worker, split_handlers) - push_manager = PushManagerAsync(apis['auth'], push_queue, sdk_metadata, telemetry_runtime_producer, processor, auth_synchronizer, streaming_api_base_url, api_key[-4:]) - return push_manager, push_queue + update_event_util = UpdateEventTypeUtilAsync() + push_queue = asyncio.Queue() + split_worker_queue = asyncio.Queue() + split_worker = SplitWorkerAsync(synchronizer.synchronize_definitions, synchronizer.synchronize_segment, split_worker_queue, synchronizer.definition_sync, synchronizer.definition_sync.definition_storage, synchronizer.segment_storage, telemetry_runtime_producer, synchronizer.definition_sync.rule_based_segment_storage, events_emitter) + await update_event_util.add_update_event(EventUpdateType.SPLIT_UPDATE, SplitChangeUpdate, split_worker.handle_feature_flag_update, split_worker, split_worker_queue) + await update_event_util.add_update_event(EventUpdateType.SPLIT_KILL, SplitKillUpdate, split_worker.handle_feature_flag_kill, split_worker, split_worker_queue) + await update_event_util.add_update_event(EventUpdateType.RB_SEGMENT_UPDATE, RBSChangeUpdate, split_worker.handle_feature_flag_update, split_worker, split_worker_queue) + + segment_worker_queue = asyncio.Queue() + segment_worker = SegmentWorkerAsync(synchronizer.synchronize_segment, segment_worker_queue) + await update_event_util.add_update_event(EventUpdateType.SEGMENT_UPDATE, SegmentChangeUpdate, segment_worker.handle_segment_change, segment_worker, segment_worker_queue) + auth_synchronizer = AuthSynchronizerAsync(apis['auth'], telemetry_runtime_producer, push_queue) + processor = MessageProcessorAsync(update_event_util, EventUpdateType) + push_manager = PushManagerAsync(apis['auth'], push_queue, sdk_metadata, telemetry_runtime_producer, processor, auth_synchronizer, update_event_util, EventUpdateType, streaming_api_base_url, api_key[-4:]) + + return push_manager, push_queue + +def _build_push_classes(synchronizer, cfg, telemetry_runtime_producer, apis, sdk_metadata, streaming_api_base_url, api_key, events_emitter): + push_queue = None + push_manager = None + if cfg['streamingEnabled']: + update_event_util = UpdateEventTypeUtil() push_queue = queue.Queue() - split_worker = SplitWorker(synchronizer.synchronize_definitions, synchronizer.synchronize_segment, queue.Queue(), synchronizer.definition_sync, synchronizer.definition_sync.definition_storage, synchronizer.segment_storage, telemetry_runtime_producer, synchronizer.definition_sync.rule_based_segment_storage) - split_handlers = { - UpdateType.SPLIT_UPDATE: split_worker.handle_feature_flag_update, - UpdateType.SPLIT_KILL: split_worker.handle_feature_flag_kill, - UpdateType.RB_SEGMENT_UPDATE: split_worker.handle_feature_flag_update - } + split_worker_queue = queue.Queue() + split_worker = SplitWorker(synchronizer.synchronize_definitions, synchronizer.synchronize_segment, split_worker_queue, synchronizer.definition_sync, synchronizer.definition_sync.definition_storage, synchronizer.segment_storage, telemetry_runtime_producer, synchronizer.definition_sync.rule_based_segment_storage, events_emitter) + update_event_util.add_update_event(EventUpdateType.SPLIT_UPDATE, SplitChangeUpdate, split_worker.handle_feature_flag_update, split_worker, split_worker_queue) + update_event_util.add_update_event(EventUpdateType.SPLIT_KILL, SplitKillUpdate, split_worker.handle_feature_flag_kill, split_worker, split_worker_queue) + update_event_util.add_update_event(EventUpdateType.RB_SEGMENT_UPDATE, RBSChangeUpdate, split_worker.handle_feature_flag_update, split_worker, split_worker_queue) + + segment_worker_queue = queue.Queue() + segment_worker = SegmentWorker(synchronizer.synchronize_segment, segment_worker_queue) + update_event_util.add_update_event(EventUpdateType.SEGMENT_UPDATE, SegmentChangeUpdate, segment_worker.handle_segment_change, segment_worker, segment_worker_queue) + auth_synchronizer = AuthSynchronizer(apis['auth'], telemetry_runtime_producer, push_queue) - processor = MessageProcessor(synchronizer, split_worker, split_handlers) - push_manager = PushManager(apis['auth'], push_queue, sdk_metadata, telemetry_runtime_producer, processor, auth_synchronizer, streaming_api_base_url, api_key[-4:]) + processor = MessageProcessor(update_event_util, EventUpdateType) + push_manager = PushManager(apis['auth'], push_queue, sdk_metadata, telemetry_runtime_producer, processor, auth_synchronizer, update_event_util, EventUpdateType, streaming_api_base_url, api_key[-4:]) return push_manager, push_queue @@ -921,23 +941,24 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl _, apis = _build_api_classes(ThreadingMode.THREADED, cfg, sdk_url, events_url, auth_api_base_url, telemetry_api_base_url, api_key, telemetry_runtime_producer, sdk_metadata) - internal_events_queue, events_manager, internal_events_task = _build_events_manager_classes(ThreadingMode.THREADED) - storages = _build_storage_classes(ThreadingMode.THREADED, internal_events_queue, telemetry_runtime_producer, cfg) + events_emitter, events_manager, internal_events_task = _build_events_manager_classes(ThreadingMode.THREADED) + storages = _build_storage_classes(ThreadingMode.THREADED, telemetry_runtime_producer, cfg) telemetry_submitter = InMemoryTelemetrySubmitter(telemetry_consumer, storages['splits'], storages['segments'], apis['telemetry']) unique_keys_tracker = UniqueKeysTracker(_UNIQUE_KEYS_CACHE_SIZE) imp_counter, imp_manager = _build_engine_classes(cfg['impressionsMode'], telemetry_runtime_producer) sender_adapter = InMemorySenderAdapter(apis['telemetry']) - synchronizers = _build_synchronizer_classes(ThreadingMode.THREADED, storages, apis, cfg, telemetry_submitter, unique_keys_tracker, imp_counter, sender_adapter) + synchronizers = _build_synchronizer_classes(ThreadingMode.THREADED, storages, apis, cfg, telemetry_submitter, unique_keys_tracker, imp_counter, sender_adapter, events_emitter) tasks = _build_sync_tasks(ThreadingMode.THREADED, synchronizers, cfg, internal_events_task) - synchronizer = Synchronizer(synchronizers, tasks) + synchronizer = Synchronizer(synchronizers, tasks, events_emitter) + synchronizer._harness_tasks._definition_task._task._main = synchronizer.synchronize_definitions preforked_initialization = cfg.get('preforkedInitialization', False) sdk_ready_flag = threading.Event() if not preforked_initialization else None - push_manager, push_queue = _build_push_classes(ThreadingMode.THREADED, synchronizer, cfg, telemetry_runtime_producer, apis, sdk_metadata, streaming_api_base_url, api_key) + push_manager, push_queue = _build_push_classes(synchronizer, cfg, telemetry_runtime_producer, apis, sdk_metadata, streaming_api_base_url, api_key, events_emitter) manager = Manager(sdk_ready_flag, synchronizer, apis['auth'], cfg['streamingEnabled'], sdk_metadata, telemetry_runtime_producer, streaming_api_base_url, api_key[-4:], push_manager, push_queue) recorder = _build_recorder(ThreadingMode.THREADED, synchronizer, cfg, imp_manager, storages, telemetry_evaluation_producer, telemetry_runtime_producer, sdk_metadata, imp_counter, unique_keys_tracker) @@ -950,14 +971,14 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl synchronizer._harness_synchronizers._segment_sync.shutdown() return SplitFactory(api_key, storages, cfg['labelsEnabled'], - recorder, internal_events_queue, events_manager, manager, None, telemetry_producer, telemetry_init_producer, telemetry_submitter, preforked_initialization=preforked_initialization, + recorder, events_emitter, events_manager, manager, None, telemetry_producer, telemetry_init_producer, telemetry_submitter, preforked_initialization=preforked_initialization, fallback_treatment_calculator=FallbackTreatmentCalculator(cfg['fallbackTreatments'])) initialization_thread = threading.Thread(target=manager.start, name="SDKInitializer", daemon=True) initialization_thread.start() return SplitFactory(api_key, storages, cfg['labelsEnabled'], - recorder, internal_events_queue, events_manager, manager, sdk_ready_flag, + recorder, events_emitter, events_manager, manager, sdk_ready_flag, telemetry_producer, telemetry_init_producer, telemetry_submitter, fallback_treatment_calculator = FallbackTreatmentCalculator(cfg['fallbackTreatments'])) @@ -978,19 +999,19 @@ async def _build_in_memory_factory_async(api_key, cfg, sdk_url=None, events_url= http_client, apis = _build_api_classes(ThreadingMode.ASYNC, cfg, sdk_url, events_url, auth_api_base_url, telemetry_api_base_url, api_key, telemetry_runtime_producer, sdk_metadata) - internal_events_queue, events_manager, internal_events_task = _build_events_manager_classes(ThreadingMode.ASYNC) - storages = _build_storage_classes(ThreadingMode.ASYNC, internal_events_queue, telemetry_runtime_producer, cfg) + events_emitter, events_manager, internal_events_task = _build_events_manager_classes(ThreadingMode.ASYNC) + storages = _build_storage_classes(ThreadingMode.ASYNC, telemetry_runtime_producer, cfg) telemetry_submitter = InMemoryTelemetrySubmitterAsync(telemetry_consumer, storages['splits'], storages['segments'], apis['telemetry']) unique_keys_tracker = UniqueKeysTrackerAsync(_UNIQUE_KEYS_CACHE_SIZE) imp_counter, imp_manager = _build_engine_classes(cfg['impressionsMode'], telemetry_runtime_producer) sender_adapter = InMemorySenderAdapterAsync(apis['telemetry']) - synchronizers = _build_synchronizer_classes(ThreadingMode.ASYNC, storages, apis, cfg, telemetry_submitter, unique_keys_tracker, imp_counter, sender_adapter) + synchronizers = _build_synchronizer_classes(ThreadingMode.ASYNC, storages, apis, cfg, telemetry_submitter, unique_keys_tracker, imp_counter, sender_adapter, events_emitter) tasks = _build_sync_tasks(ThreadingMode.ASYNC, synchronizers, cfg, internal_events_task) - synchronizer = SynchronizerAsync(synchronizers, tasks) + synchronizer = SynchronizerAsync(synchronizers, tasks, events_emitter) - push_manager, push_queue = _build_push_classes(ThreadingMode.ASYNC, synchronizer, cfg, telemetry_runtime_producer, apis, sdk_metadata, streaming_api_base_url, api_key) + push_manager, push_queue = await _build_push_classes_async(synchronizer, cfg, telemetry_runtime_producer, apis, sdk_metadata, streaming_api_base_url, api_key, events_emitter) manager = ManagerAsync(synchronizer, apis['auth'], cfg['streamingEnabled'], sdk_metadata, telemetry_runtime_producer, streaming_api_base_url, api_key[-4:], push_manager, push_queue) @@ -1002,7 +1023,7 @@ async def _build_in_memory_factory_async(api_key, cfg, sdk_url=None, events_url= manager_start_task = asyncio.get_running_loop().create_task(manager.start()) return SplitFactoryAsync(api_key, storages, cfg['labelsEnabled'], - recorder, internal_events_queue, events_manager, manager, + recorder, events_emitter, events_manager, manager, telemetry_producer, telemetry_init_producer, telemetry_submitter, manager_start_task=manager_start_task, api_client=http_client, fallback_treatment_calculator=FallbackTreatmentCalculator(cfg['fallbackTreatments'])) @@ -1011,14 +1032,15 @@ def _build_redis_factory(api_key, cfg): """Build and return a split factory with redis-based storage.""" sdk_metadata = util.get_metadata(cfg) redis_adapter = redis.build(cfg) - storages = _build_storage_classes(ThreadingMode.THREADED, None, None, cfg, sdk_metadata, redis_adapter) + storages = _build_storage_classes(ThreadingMode.THREADED, None, cfg, sdk_metadata, redis_adapter) telemetry_producer, telemetry_runtime_producer, telemetry_init_producer, telemetry_submitter = _build_telemetry_classes(cfg['storageType'], ThreadingMode.THREADED, storages['telemetry']) unique_keys_tracker = UniqueKeysTracker(_UNIQUE_KEYS_CACHE_SIZE) imp_counter, imp_manager = _build_engine_classes(cfg['impressionsMode'], telemetry_runtime_producer) sender_adapter = RedisSenderAdapter(redis_adapter) - synchronizers = _build_synchronizer_classes(ThreadingMode.THREADED, storages, None, cfg, None, unique_keys_tracker, imp_counter, sender_adapter) + events_emitter, events_manager, _ = _build_events_manager_classes(ThreadingMode.THREADED) + synchronizers = _build_synchronizer_classes(ThreadingMode.THREADED, storages, None, cfg, None, unique_keys_tracker, imp_counter, sender_adapter, events_emitter) tasks = _build_sync_tasks(ThreadingMode.THREADED, synchronizers, cfg, None) synchronizer = RedisSynchronizer(synchronizers, tasks) @@ -1028,14 +1050,13 @@ def _build_redis_factory(api_key, cfg): initialization_thread.start() telemetry_init_producer.record_config(cfg, {}, 0, 0) - internal_events_queue, events_manager, _ = _build_events_manager_classes(ThreadingMode.THREADED) split_factory = SplitFactory( api_key, storages, cfg['labelsEnabled'], recorder, - internal_events_queue, + events_emitter, events_manager, manager, sdk_ready_flag=None, @@ -1053,7 +1074,7 @@ async def _build_redis_factory_async(api_key, cfg): """Build and return a split factory with redis-based storage.""" sdk_metadata = util.get_metadata(cfg) redis_adapter = await redis.build_async(cfg) - storages = _build_storage_classes(ThreadingMode.ASYNC, None, None, cfg, sdk_metadata, redis_adapter) + storages = _build_storage_classes(ThreadingMode.ASYNC, None, cfg, sdk_metadata, redis_adapter) storages['telemetry'] = await RedisTelemetryStorageAsync.create(redis_adapter, sdk_metadata) telemetry_producer, telemetry_runtime_producer, telemetry_init_producer, telemetry_submitter = _build_telemetry_classes(cfg['storageType'], ThreadingMode.ASYNC, storages['telemetry']) @@ -1061,7 +1082,8 @@ async def _build_redis_factory_async(api_key, cfg): imp_counter, imp_manager = _build_engine_classes(cfg['impressionsMode'], telemetry_runtime_producer) sender_adapter = RedisSenderAdapterAsync(redis_adapter) - synchronizers = _build_synchronizer_classes(ThreadingMode.ASYNC, storages, None, cfg, None, unique_keys_tracker, imp_counter, sender_adapter) + events_emitter, events_manager, _ = _build_events_manager_classes(ThreadingMode.ASYNC) + synchronizers = _build_synchronizer_classes(ThreadingMode.ASYNC, storages, None, cfg, None, unique_keys_tracker, imp_counter, sender_adapter, events_emitter) tasks = _build_sync_tasks(ThreadingMode.ASYNC, synchronizers, cfg, None) synchronizer = RedisSynchronizerAsync(synchronizers, tasks) @@ -1069,14 +1091,13 @@ async def _build_redis_factory_async(api_key, cfg): manager = RedisManagerAsync(synchronizer) await telemetry_init_producer.record_config(cfg, {}, 0, 0) manager.start() - internal_events_queue, events_manager, _ = _build_events_manager_classes(ThreadingMode.ASYNC) split_factory = SplitFactoryAsync( api_key, storages, cfg['labelsEnabled'], recorder, - internal_events_queue, + events_emitter, events_manager, manager, telemetry_producer=telemetry_producer, @@ -1098,14 +1119,15 @@ def _build_pluggable_factory(api_key, cfg): pluggable_adapter = cfg.get('storageWrapper') storage_prefix = cfg.get('storagePrefix') - storages = _build_storage_classes(ThreadingMode.THREADED, None, None, cfg, sdk_metadata, pluggable_adapter, storage_prefix) + storages = _build_storage_classes(ThreadingMode.THREADED, None, cfg, sdk_metadata, pluggable_adapter, storage_prefix) telemetry_producer, telemetry_runtime_producer, telemetry_init_producer, telemetry_submitter = _build_telemetry_classes(cfg['storageType'], ThreadingMode.THREADED, storages['telemetry']) unique_keys_tracker = UniqueKeysTracker(_UNIQUE_KEYS_CACHE_SIZE) imp_counter, imp_manager = _build_engine_classes(cfg['impressionsMode'], telemetry_runtime_producer) sender_adapter = PluggableSenderAdapter(pluggable_adapter, storage_prefix) - synchronizers = _build_synchronizer_classes(ThreadingMode.THREADED, storages, None, cfg, None, unique_keys_tracker, imp_counter, sender_adapter) + events_emitter, events_manager, _ = _build_events_manager_classes(ThreadingMode.THREADED) + synchronizers = _build_synchronizer_classes(ThreadingMode.THREADED, storages, None, cfg, None, unique_keys_tracker, imp_counter, sender_adapter, events_emitter) tasks = _build_sync_tasks(ThreadingMode.THREADED, synchronizers, cfg, None) synchronizer = RedisSynchronizer(synchronizers, tasks) @@ -1128,14 +1150,13 @@ def _build_pluggable_factory(api_key, cfg): initialization_thread.start() telemetry_init_producer.record_config(cfg, {}, 0, 0) - internal_events_queue, events_manager, _ = _build_events_manager_classes(ThreadingMode.THREADED) split_factory = SplitFactory( api_key, storages, cfg['labelsEnabled'], recorder, - internal_events_queue, + events_emitter, events_manager, manager, sdk_ready_flag=None, @@ -1157,7 +1178,7 @@ async def _build_pluggable_factory_async(api_key, cfg): pluggable_adapter = cfg.get('storageWrapper') storage_prefix = cfg.get('storagePrefix') - storages = _build_storage_classes(ThreadingMode.ASYNC, None, None, cfg, sdk_metadata, pluggable_adapter, storage_prefix) + storages = _build_storage_classes(ThreadingMode.ASYNC, None, cfg, sdk_metadata, pluggable_adapter, storage_prefix) storages['telemetry'] = await PluggableTelemetryStorageAsync.create(pluggable_adapter, sdk_metadata, storage_prefix) telemetry_producer, telemetry_runtime_producer, telemetry_init_producer, telemetry_submitter = _build_telemetry_classes(cfg['storageType'], ThreadingMode.ASYNC, storages['telemetry']) @@ -1165,7 +1186,8 @@ async def _build_pluggable_factory_async(api_key, cfg): imp_counter, imp_manager = _build_engine_classes(cfg['impressionsMode'], telemetry_runtime_producer) sender_adapter = PluggableSenderAdapterAsync(pluggable_adapter, storage_prefix) - synchronizers = _build_synchronizer_classes(ThreadingMode.ASYNC, storages, None, cfg, None, unique_keys_tracker, imp_counter, sender_adapter) + events_emitter, events_manager, _ = _build_events_manager_classes(ThreadingMode.ASYNC) + synchronizers = _build_synchronizer_classes(ThreadingMode.ASYNC, storages, None, cfg, None, unique_keys_tracker, imp_counter, sender_adapter, events_emitter) tasks = _build_sync_tasks(ThreadingMode.ASYNC, synchronizers, cfg, None) synchronizer = RedisSynchronizerAsync(synchronizers, tasks) @@ -1186,14 +1208,13 @@ async def _build_pluggable_factory_async(api_key, cfg): manager = RedisManagerAsync(synchronizer) manager.start() await telemetry_init_producer.record_config(cfg, {}, 0, 0) - internal_events_queue, events_manager, _ = _build_events_manager_classes(ThreadingMode.ASYNC) split_factory = SplitFactoryAsync( api_key, storages, cfg['labelsEnabled'], recorder, - internal_events_queue, + events_emitter, events_manager, manager, telemetry_producer=telemetry_producer, @@ -1215,10 +1236,11 @@ def _build_localhost_factory(cfg): telemetry_evaluation_producer = telemetry_producer.get_telemetry_evaluation_producer() internal_events_queue = queue.Queue() + events_emitter = EventsEmitter(internal_events_queue) storages = { - 'splits': InMemorySplitStorage(internal_events_queue, cfg['flagSetsFilter'] if cfg['flagSetsFilter'] is not None else []), - 'segments': InMemorySegmentStorage(internal_events_queue), # not used, just to avoid possible future errors. - 'rule_based_segments': InMemoryRuleBasedSegmentStorage(internal_events_queue), + 'splits': InMemorySplitStorage(cfg['flagSetsFilter'] if cfg['flagSetsFilter'] is not None else []), + 'segments': InMemorySegmentStorage(), # not used, just to avoid possible future errors. + 'rule_based_segments': InMemoryRuleBasedSegmentStorage(), 'impressions': LocalhostImpressionsStorage(), 'events': LocalhostEventsStorage(), } @@ -1280,7 +1302,7 @@ def _build_localhost_factory(cfg): storages, False, recorder, - internal_events_queue, + events_emitter, events_manager, manager, ready_event, @@ -1298,13 +1320,14 @@ async def _build_localhost_factory_async(cfg): telemetry_evaluation_producer = telemetry_producer.get_telemetry_evaluation_producer() internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) internal_events_task = EventsTaskAsync(events_manager.notify_internal_event, internal_events_queue) storages = { - 'splits': InMemorySplitStorageAsync(internal_events_queue), - 'segments': InMemorySegmentStorageAsync(internal_events_queue), # not used, just to avoid possible future errors. - 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(internal_events_queue), + 'splits': InMemorySplitStorageAsync(), + 'segments': InMemorySegmentStorageAsync(), # not used, just to avoid possible future errors. + 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(), 'impressions': LocalhostImpressionsStorageAsync(), 'events': LocalhostEventsStorageAsync(), } @@ -1363,7 +1386,7 @@ async def _build_localhost_factory_async(cfg): storages, False, recorder, - internal_events_queue, + events_emitter, events_manager, manager, telemetry_producer=telemetry_producer, diff --git a/splitio/events/__init__.py b/splitio/events/__init__.py new file mode 100644 index 00000000..a5927c69 --- /dev/null +++ b/splitio/events/__init__.py @@ -0,0 +1 @@ +# Storage tests module diff --git a/splitio/events/events_emitter.py b/splitio/events/events_emitter.py new file mode 100644 index 00000000..9330abdd --- /dev/null +++ b/splitio/events/events_emitter.py @@ -0,0 +1,37 @@ +"""Events Manager.""" +import logging + +from splitio_commons.events.events_metadata import EventsMetadata +from splitio_commons.models.notification import SdkInternalEventNotification + +_LOGGER = logging.getLogger(__name__) + +class EventsEmitter(object): + """Events Emitter class.""" + + def __init__(self, internal_event_queue): + """ + Construct Events Emitter instance. + """ + self._internal_event_queue = internal_event_queue + + def emit(self, sdk_internal_event_type, sdk_event_type, event_metadata={}): + metadata = None + if sdk_event_type != None: + _LOGGER.debug("Emitting SDKEventType %s", sdk_event_type) + metadata = EventsMetadata(sdk_event_type, event_metadata) + + self._internal_event_queue.put( + SdkInternalEventNotification( + sdk_internal_event_type, metadata)) + + async def emit_async(self, sdk_internal_event_type, sdk_event_type, event_metadata={}): + metadata = None + if sdk_event_type != None: + _LOGGER.debug("Emitting SDKEventType %s", sdk_event_type) + metadata = EventsMetadata(sdk_event_type, event_metadata) + + await self._internal_event_queue.put( + SdkInternalEventNotification( + sdk_internal_event_type, + metadata)) diff --git a/splitio/push/models.py b/splitio/push/models.py new file mode 100644 index 00000000..c477ff8b --- /dev/null +++ b/splitio/push/models.py @@ -0,0 +1,164 @@ +from enum import Enum +from itertools import chain + +from splitio_commons.push.parser import BaseUpdate +from splitio_commons.push.event_update_type import EventUpdateType as BaseUpdateType + +class EventUpdateType(Enum): + """Message type enumeration.""" + + SPLIT_UPDATE = 'SPLIT_UPDATE' + SPLIT_KILL = 'SPLIT_KILL' + RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE' + +EventUpdateType = Enum('EventUpdateType', [(m.name, m.value) for m in chain(EventUpdateType, BaseUpdateType)]) + +class SplitChangeUpdate(BaseUpdate): + """Feature flag Change notification.""" + + def __init__(self, channel, timestamp, change_number, data, update_type_class): + """Class constructor.""" + BaseUpdate.__init__(self, channel, timestamp, change_number) + self._previous_change_number = data.get('pcn') + self._object_definition = data.get('d') + self._compression = data.get('c') + self._update_type_class = update_type_class + + @property + def update_type(self): # pylint:disable=no-self-use + """ + Return the message type. + + :returns: The type of this parsed Update. + :rtype: UpdateType + """ + return self._update_type_class.SPLIT_UPDATE + + @property + def previous_change_number(self): # pylint:disable=no-self-use + """ + Return previous change number + :returns: The previous change number + :rtype: int + """ + return self._previous_change_number + + @property + def object_definition(self): # pylint:disable=no-self-use + """ + Return feature flag definition + :returns: The new feature flag definition + :rtype: str + """ + return self._object_definition + + @property + def compression(self): # pylint:disable=no-self-use + """ + Return previous compression type + :returns: The compression type + :rtype: int + """ + return self._compression + + def __str__(self): + """Return string representation.""" + return "SplitChange - changeNumber=%d" % (self.change_number) + + +class SplitKillUpdate(BaseUpdate): + """Feature flag Kill notification.""" + + def __init__(self, channel, timestamp, change_number, data, update_type_class): # pylint:disable=too-many-arguments + """Class constructor.""" + BaseUpdate.__init__(self, channel, timestamp, change_number) + self._feature_flag_name = data.get('feature_flag_name') + self._default_treatment = data.get('default_treatment') + self._update_type_class = update_type_class + + @property + def update_type(self): # pylint:disable=no-self-use + """ + Return the message type. + + :returns: The type of this parsed Update. + :rtype: UpdateType + """ + return self._update_type_class.SPLIT_KILL + + @property + def feature_flag_name(self): + """ + Return the name of the killed feature flag. + + :returns: name of the killed feature flag + :rtype: str + """ + return self._feature_flag_name + + @property + def default_treatment(self): + """ + Return the default treatment. + + :returns: default treatment + :rtype: str + """ + return self._default_treatment + + def __str__(self): + """Return string representation.""" + return "SplitKill - changeNumber=%d, name=%s, defaultTreatment=%s" % \ + (self.change_number, self.feature_flag_name, self.default_treatment) + +class RBSChangeUpdate(BaseUpdate): + """rbs Change notification.""" + + def __init__(self, channel, timestamp, change_number, data, update_type_class): + """Class constructor.""" + BaseUpdate.__init__(self, channel, timestamp, change_number) + self._previous_change_number = data.get('pcn') + self._object_definition = data.get('d') + self._compression = data.get('c') + self._update_type_class = update_type_class + + @property + def update_type(self): # pylint:disable=no-self-use + """ + Return the message type. + + :returns: The type of this parsed Update. + :rtype: UpdateType + """ + return self._update_type_class.RB_SEGMENT_UPDATE + + @property + def previous_change_number(self): # pylint:disable=no-self-use + """ + Return previous change number + :returns: The previous change number + :rtype: int + """ + return self._previous_change_number + + @property + def object_definition(self): # pylint:disable=no-self-use + """ + Return rbs definition + :returns: The new rbs definition + :rtype: str + """ + return self._object_definition + + @property + def compression(self): # pylint:disable=no-self-use + """ + Return previous compression type + :returns: The compression type + :rtype: int + """ + return self._compression + + def __str__(self): + """Return string representation.""" + return "RBSChange - changeNumber=%d" % (self.change_number) \ No newline at end of file diff --git a/splitio/push/workers.py b/splitio/push/workers.py index c16d0eeb..97a78404 100644 --- a/splitio/push/workers.py +++ b/splitio/push/workers.py @@ -1,20 +1,16 @@ """Segment changes processing worker.""" import logging import threading -import abc -import gzip -import zlib -import base64 import json -from enum import Enum -from queue import Queue from splitio.optional.loaders import asyncio from splitio.models.splits import from_raw from splitio_commons.models.rule_based_segments import from_raw as rbs_from_raw from splitio_commons.models.telemetry import UpdateFromSSE from splitio_commons.push import SplitStorageException -from splitio_commons.push.parser import UpdateType +from splitio.push.models import EventUpdateType +from splitio_commons.models.events import SdkInternalEvent +from splitio_commons.events.events_metadata import SdkEventType from splitio_commons.push.workers import WorkerBase from splitio_commons.optional.loaders import asyncio from splitio_commons.util.storage_helper import update_definition_storage, update_definition_storage_async, \ @@ -27,7 +23,7 @@ class SplitWorker(WorkerBase): _centinel = object() - def __init__(self, synchronize_feature_flag, synchronize_segment, feature_flag_queue, split_synchronizer, feature_flag_storage, segment_storage, telemetry_runtime_producer, rule_based_segment_storage): + def __init__(self, synchronize_feature_flag, synchronize_segment, feature_flag_queue, split_synchronizer, feature_flag_storage, segment_storage, telemetry_runtime_producer, rule_based_segment_storage, events_emitter): """ Class constructor. @@ -56,6 +52,7 @@ def __init__(self, synchronize_feature_flag, synchronize_segment, feature_flag_q self._telemetry_runtime_producer = telemetry_runtime_producer self._rule_based_segment_storage = rule_based_segment_storage self._synchronizer = split_synchronizer + self._events_emitter = events_emitter def is_running(self): """Return whether the working is running.""" @@ -64,9 +61,13 @@ def is_running(self): def _apply_iff_if_needed(self, event): if not self._check_instant_ff_update(event): return False + try: - if event.update_type == UpdateType.SPLIT_UPDATE: - new_feature_flag = from_raw(json.loads(self._get_object_definition(event))) + _LOGGER.error("inside iff") + _LOGGER.error(event.update_type) + if event.update_type == EventUpdateType.SPLIT_UPDATE: + _LOGGER.error(json.loads(self._get_object_definition(event))) + new_feature_flag = from_raw(json.loads(self._get_object_definition(event))) segment_list = update_definition_storage(self._feature_flag_storage, [new_feature_flag], event.change_number) for segment_name in segment_list: if self._segment_storage.get(segment_name) is None: @@ -76,6 +77,9 @@ def _apply_iff_if_needed(self, event): referenced_rbs = self._get_referenced_rbs(new_feature_flag) self._fetch_rbs_segment_if_needed(referenced_rbs, event) self._telemetry_runtime_producer.record_update_from_sse(UpdateFromSSE.SPLIT_UPDATE) + self._events_emitter.emit(SdkInternalEvent.FLAGS_UPDATED, + SdkEventType.FLAG_UPDATE, + [new_feature_flag.name]) else: new_rbs = rbs_from_raw(json.loads(self._get_object_definition(event))) segment_list = update_rule_based_segment_storage(self._rule_based_segment_storage, [new_rbs], event.change_number) @@ -84,9 +88,12 @@ def _apply_iff_if_needed(self, event): _LOGGER.debug(self._fetching_segment.format(segment_name=segment_name)) self._segment_handler(segment_name, event.change_number) self._telemetry_runtime_producer.record_update_from_sse(UpdateFromSSE.RBS_UPDATE) + self._events_emitter.emit(SdkInternalEvent.RB_SEGMENTS_UPDATED, + SdkEventType.SEGMENTS_UPDATE) return True except Exception as e: + _LOGGER.error(str(e)) raise SplitStorageException(e) def _fetch_rbs_segment_if_needed(self, referenced_rbs, event): @@ -95,10 +102,10 @@ def _fetch_rbs_segment_if_needed(self, referenced_rbs, event): self._handler(None, event.change_number) def _check_instant_ff_update(self, event): - if event.update_type == UpdateType.SPLIT_UPDATE and event.compression is not None and event.previous_change_number == self._feature_flag_storage.get_change_number(): + if event.update_type == EventUpdateType.SPLIT_UPDATE and event.compression is not None and event.previous_change_number == self._feature_flag_storage.get_change_number(): return True - if event.update_type == UpdateType.RB_SEGMENT_UPDATE and event.compression is not None and event.previous_change_number == self._rule_based_segment_storage.get_change_number(): + if event.update_type == EventUpdateType.RB_SEGMENT_UPDATE and event.compression is not None and event.previous_change_number == self._rule_based_segment_storage.get_change_number(): return True return False @@ -114,7 +121,7 @@ def _run(self): if event == self._centinel: continue - _LOGGER.debug('Processing feature flag update %d', event.change_number) + _LOGGER.error('Processing feature flag update %d', event.change_number) try: if self._apply_iff_if_needed(event): continue @@ -124,6 +131,7 @@ def _run(self): till, rbs_till = self._check_update_type(till, rbs_till, event) _LOGGER.error("synching") sync_result = self._handler(till, rbs_till) + _LOGGER.error("after synching") if not sync_result.success and sync_result.error_code is not None and sync_result.error_code == 414: _LOGGER.error("URI too long exception caught, sync failed") @@ -138,7 +146,7 @@ def _run(self): _LOGGER.debug('Exception information: ', exc_info=True) def _check_update_type(self, till, rbs_till, event): - if event.update_type == UpdateType.SPLIT_UPDATE: + if event.update_type == EventUpdateType.SPLIT_UPDATE: till = event.change_number else: rbs_till = event.change_number @@ -181,7 +189,7 @@ def handle_feature_flag_kill(self, event): :param event: Incoming feature flag kill event :type event: splitio.push.parser.SplitKillUpdate """ - self._synchronizer.kill_definition(event.definition_name, event.default_treatment, + self._synchronizer.kill_definition(event.feature_flag_name, event.default_treatment, event.change_number) self._feature_flag_queue.put(event) @@ -190,7 +198,7 @@ class SplitWorkerAsync(WorkerBase): _centinel = object() - def __init__(self, synchronize_feature_flag, synchronize_segment, feature_flag_queue, split_synchronizer, feature_flag_storage, segment_storage, telemetry_runtime_producer, rule_based_segment_storage): + def __init__(self, synchronize_feature_flag, synchronize_segment, feature_flag_queue, split_synchronizer, feature_flag_storage, segment_storage, telemetry_runtime_producer, rule_based_segment_storage, events_emitter): """ Class constructor. @@ -218,6 +226,7 @@ def __init__(self, synchronize_feature_flag, synchronize_segment, feature_flag_q self._telemetry_runtime_producer = telemetry_runtime_producer self._rule_based_segment_storage = rule_based_segment_storage self._synchronizer = split_synchronizer + self._events_emitter = events_emitter def is_running(self): """Return whether the working is running.""" @@ -226,8 +235,9 @@ def is_running(self): async def _apply_iff_if_needed(self, event): if not await self._check_instant_ff_update(event): return False + try: - if event.update_type == UpdateType.SPLIT_UPDATE: + if event.update_type == EventUpdateType.SPLIT_UPDATE: new_feature_flag = from_raw(json.loads(self._get_object_definition(event))) segment_list = await update_definition_storage_async(self._feature_flag_storage, [new_feature_flag], event.change_number) for segment_name in segment_list: @@ -238,17 +248,23 @@ async def _apply_iff_if_needed(self, event): referenced_rbs = self._get_referenced_rbs(new_feature_flag) await self._fetch_rbs_segment_if_needed(referenced_rbs, event) await self._telemetry_runtime_producer.record_update_from_sse(UpdateFromSSE.SPLIT_UPDATE) + await self._events_emitter.emit(SdkInternalEvent.FLAGS_UPDATED, + SdkEventType.FLAG_UPDATE, + [new_feature_flag.name]) else: - new_rbs = rbs_from_raw(json.loads(self._get_object_definition(event))) + new_rbs = rbs_from_raw(json.loads(self._get_object_definition(event))) segment_list = await update_rule_based_segment_storage_async(self._rule_based_segment_storage, [new_rbs], event.change_number) for segment_name in segment_list: if await self._segment_storage.get(segment_name) is None: _LOGGER.debug(self._fetching_segment.format(segment_name=segment_name)) await self._segment_handler(segment_name, event.change_number) - await self._telemetry_runtime_producer.record_update_from_sse(UpdateFromSSE.RBS_UPDATE) + await self._telemetry_runtime_producer.record_update_from_sse(UpdateFromSSE.RBS_UPDATE) + await self._events_emitter.emit(SdkInternalEvent.RB_SEGMENTS_UPDATED, + SdkEventType.SEGMENTS_UPDATE) return True except Exception as e: + _LOGGER.error(exc_info=True) raise SplitStorageException(e) async def _fetch_rbs_segment_if_needed(self, referenced_rbs, event): @@ -257,10 +273,10 @@ async def _fetch_rbs_segment_if_needed(self, referenced_rbs, event): await self._handler(None, event.change_number) async def _check_instant_ff_update(self, event): - if event.update_type == UpdateType.SPLIT_UPDATE and event.compression is not None and event.previous_change_number == await self._feature_flag_storage.get_change_number(): + if event.update_type == EventUpdateType.SPLIT_UPDATE and event.compression is not None and event.previous_change_number == await self._feature_flag_storage.get_change_number(): return True - if event.update_type == UpdateType.RB_SEGMENT_UPDATE and event.compression is not None and event.previous_change_number == await self._rule_based_segment_storage.get_change_number(): + if event.update_type == EventUpdateType.RB_SEGMENT_UPDATE and event.compression is not None and event.previous_change_number == await self._rule_based_segment_storage.get_change_number(): return True return False @@ -279,7 +295,7 @@ async def _run(self): continue till = None rbs_till = None - if event.update_type == UpdateType.SPLIT_UPDATE: + if event.update_type == EventUpdateType.SPLIT_UPDATE: till = event.change_number else: rbs_till = event.change_number @@ -326,6 +342,6 @@ async def handle_feature_flag_kill(self, event): :param event: Incoming feature_flag kill event :type event: splitio.push.parser.SplitKillUpdate """ - await self._synchronizer.kill_definition(event.definition_name, event.default_treatment, + await self._synchronizer.kill_definition(event.feature_flag_name, event.default_treatment, event.change_number) await self._feature_flag_queue.put(event) diff --git a/splitio/storage/inmemory.py b/splitio/storage/inmemory.py index c4830acd..d02c9d23 100644 --- a/splitio/storage/inmemory.py +++ b/splitio/storage/inmemory.py @@ -111,9 +111,9 @@ def kill_locally(self, split_name, default_treatment, change_number): class InMemorySplitStorage(InMemoryDefinitionStorage): - def __init__(self, internal_event_queue, flag_sets=[]): + def __init__(self, flag_sets=[]): """Constructor.""" - InMemoryDefinitionStorage.__init__(self, internal_event_queue, flag_sets) + InMemoryDefinitionStorage.__init__(self, flag_sets) def get_splits_count(self): return self.get_definitions_count() @@ -129,9 +129,9 @@ def get_feature_flags_by_sets(self, sets): class InMemorySplitStorageAsync(InMemoryDefinitionStorageAsync): - def __init__(self, internal_event_queue, flag_sets=[]): + def __init__(self, flag_sets=[]): """Constructor.""" - InMemoryDefinitionStorageAsync.__init__(self, internal_event_queue, flag_sets) + InMemoryDefinitionStorageAsync.__init__(self, flag_sets) async def get_splits_count(self): return await self.get_definitions_count() diff --git a/tests/client/test_client.py b/tests/client/test_client.py index 91f1db5a..ef7b6ce2 100644 --- a/tests/client/test_client.py +++ b/tests/client/test_client.py @@ -13,6 +13,7 @@ from splitio_commons.models.fallback_treatment import FallbackTreatment from splitio_commons.models.impressions import Impression, Label from splitio_commons.models.events import Event, EventWrapper, SdkEvent +from splitio.events.events_emitter import EventsEmitter from splitio_commons.storage import SegmentStorage, ImpressionStorage, EventStorage, RuleBasedSegmentsStorage from splitio.storage.inmemory import InMemorySplitStorage, InMemorySplitStorageAsync, SplitStorage from splitio_commons.storage.inmemmory import InMemorySegmentStorage, \ @@ -38,9 +39,10 @@ def test_get_treatment(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(100000, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -66,7 +68,7 @@ def synchronize_config(*_): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -118,9 +120,10 @@ def test_get_treatment_with_config(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) @@ -138,7 +141,7 @@ def test_get_treatment_with_config(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -198,9 +201,10 @@ def test_get_treatments(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) @@ -219,7 +223,7 @@ def test_get_treatments(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -281,9 +285,10 @@ def test_get_treatments_by_flag_set(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) @@ -302,7 +307,7 @@ def test_get_treatments_by_flag_set(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -363,9 +368,10 @@ def test_get_treatments_by_flag_sets(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) @@ -384,7 +390,7 @@ def test_get_treatments_by_flag_sets(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -445,9 +451,10 @@ def test_get_treatments_with_config(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) @@ -465,7 +472,7 @@ def test_get_treatments_with_config(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -531,9 +538,10 @@ def test_get_treatments_with_config_by_flag_set(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) @@ -552,7 +560,7 @@ def test_get_treatments_with_config_by_flag_set(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -615,9 +623,10 @@ def test_get_treatments_with_config_by_flag_sets(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) @@ -635,7 +644,7 @@ def test_get_treatments_with_config_by_flag_sets(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -698,9 +707,10 @@ def test_impression_toggle_optimized(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -725,7 +735,7 @@ def synchronize_config(*_): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -765,9 +775,10 @@ def test_impression_toggle_debug(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -792,7 +803,7 @@ def synchronize_config(*_): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -832,9 +843,10 @@ def test_impression_toggle_none(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -859,7 +871,7 @@ def synchronize_config(*_): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -898,6 +910,7 @@ def test_destroy(self, mocker): telemetry_producer = TelemetryStorageProducer(telemetry_storage) recorder = StandardRecorder(None, None, impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) factory = SplitFactory(mocker.Mock(), {'splits': split_storage, 'segments': segment_storage, @@ -906,7 +919,7 @@ def test_destroy(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -941,6 +954,7 @@ def test_track(self, mocker): telemetry_producer = TelemetryStorageProducer(telemetry_storage) recorder = StandardRecorder(None, None, impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) factory = SplitFactory(mocker.Mock(), {'splits': split_storage, 'segments': segment_storage, @@ -949,7 +963,7 @@ def test_track(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -984,9 +998,10 @@ def test_evaluations_before_running_post_fork(self, mocker): impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() split_storage.update([from_raw(splits_json['splitChange1_1']['ff']['d'][0])], [], -1) destroyed_property = mocker.PropertyMock() destroyed_property.return_value = False @@ -1002,7 +1017,7 @@ def test_evaluations_before_running_post_fork(self, mocker): 'events': mocker.Mock()}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -1069,9 +1084,10 @@ def test_telemetry_not_ready(self, mocker): impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() split_storage.update([from_raw(splits_json['splitChange1_1']['ff']['d'][0])], [], -1) recorder = StandardRecorder(None, None, impmanager, mocker.Mock(), mocker.Mock(), telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) factory = SplitFactory('localhost', @@ -1082,7 +1098,7 @@ def test_telemetry_not_ready(self, mocker): 'events': mocker.Mock()}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -1105,10 +1121,11 @@ def synchronize_config(*_): def test_telemetry_record_treatment_exception(self, mocker): events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() split_storage.update([from_raw(splits_json['splitChange1_1']['ff']['d'][0])], [], -1) segment_storage = mocker.Mock(spec=SegmentStorage) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + rb_segment_storage = InMemoryRuleBasedSegmentStorage() impression_storage = mocker.Mock(spec=ImpressionStorage) event_storage = mocker.Mock(spec=EventStorage) destroyed_property = mocker.PropertyMock() @@ -1129,7 +1146,7 @@ def test_telemetry_record_treatment_exception(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), impmanager, mocker.Mock(), @@ -1213,9 +1230,10 @@ def test_telemetry_method_latency(self, mocker): event_storage = mocker.Mock(spec=EventStorage) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() split_storage.update([from_raw(splits_json['splitChange1_1']['ff']['d'][0])], [], -1) recorder = StandardRecorder(None, None, impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) destroyed_property = mocker.PropertyMock() @@ -1232,7 +1250,7 @@ def test_telemetry_method_latency(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), impmanager, mocker.Mock(), @@ -1297,6 +1315,7 @@ def test_telemetry_track_exception(self, mocker): telemetry_producer = TelemetryStorageProducer(telemetry_storage) recorder = StandardRecorder(None, None, impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) factory = SplitFactory(mocker.Mock(), {'splits': split_storage, 'segments': segment_storage, @@ -1305,7 +1324,7 @@ def test_telemetry_track_exception(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), impmanager, mocker.Mock(), @@ -1331,9 +1350,10 @@ def test_impressions_properties(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -1360,7 +1380,7 @@ def synchronize_config(*_): 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -1467,6 +1487,7 @@ def fetch_many_rbs(*_): impmanager = ImpressionManager(StrategyOptimizedMode(), StrategyNoneMode(), telemetry_producer.get_telemetry_runtime_producer()) recorder = StandardRecorder(None, None, impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) internal_events_queue = queue.Queue() + events_emitter = EventsEmitter(internal_events_queue) factory = SplitFactory(mocker.Mock(), {'splits': split_storage, 'segments': segment_storage, @@ -1475,7 +1496,7 @@ def fetch_many_rbs(*_): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, mocker.Mock(), impmanager, mocker.Mock(), @@ -1608,6 +1629,7 @@ def test_fallback_treatment_exception(self, mocker): impmanager = ImpressionManager(StrategyOptimizedMode(), StrategyNoneMode(), telemetry_producer.get_telemetry_runtime_producer()) recorder = StandardRecorder(None, None, impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) internal_events_queue = queue.Queue() + events_emitter = EventsEmitter(internal_events_queue) factory = SplitFactory(mocker.Mock(), {'splits': split_storage, 'segments': segment_storage, @@ -1616,7 +1638,7 @@ def test_fallback_treatment_exception(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, mocker.Mock(), impmanager, mocker.Mock(), @@ -1679,6 +1701,7 @@ def test_fallback_treatment_not_ready_impressions(self, mocker): impmanager = ImpressionManager(StrategyOptimizedMode(), StrategyNoneMode(), telemetry_producer.get_telemetry_runtime_producer()) recorder = StandardRecorder(None, None, impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) internal_events_queue = queue.Queue() + events_emitter = EventsEmitter(internal_events_queue) factory = SplitFactory(mocker.Mock(), {'splits': split_storage, 'segments': segment_storage, @@ -1687,7 +1710,7 @@ def test_fallback_treatment_not_ready_impressions(self, mocker): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, mocker.Mock(), impmanager, mocker.Mock(), @@ -1758,6 +1781,7 @@ class ClientAsyncTests(object): # pylint: disable=too-few-public-methods async def test_get_treatment_async(self, mocker): """Test get_treatment_async execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -1765,9 +1789,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -1793,7 +1817,7 @@ async def synchronize_config(*_): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -1838,6 +1862,7 @@ def _raise(*_): async def test_get_treatment_with_config_async(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -1845,9 +1870,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -1866,7 +1891,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -1923,6 +1948,7 @@ def _raise(*_): async def test_get_treatments_async(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -1930,9 +1956,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -1951,7 +1977,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2011,6 +2037,7 @@ def _raise(*_): async def test_get_treatments_by_flag_set_async(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2018,9 +2045,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -2039,7 +2066,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2099,6 +2126,7 @@ def _raise(*_): async def test_get_treatments_by_flag_sets_async(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2106,9 +2134,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -2127,7 +2155,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2187,6 +2215,7 @@ def _raise(*_): async def test_get_treatments_with_config(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2194,9 +2223,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -2214,7 +2243,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2279,6 +2308,7 @@ def _raise(*_): async def test_get_treatments_with_config_by_flag_set(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2286,9 +2316,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -2306,7 +2336,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2371,6 +2401,7 @@ def _raise(*_): async def test_get_treatments_with_config_by_flag_sets(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2378,9 +2409,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -2398,7 +2429,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2463,6 +2494,7 @@ def _raise(*_): async def test_impression_toggle_optimized(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2470,9 +2502,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -2493,7 +2525,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2534,6 +2566,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): async def test_impression_toggle_debug(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2541,9 +2574,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -2564,7 +2597,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2602,6 +2635,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): async def test_impression_toggle_none(self, mocker): """Test get_treatment execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2609,9 +2643,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -2632,7 +2666,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2660,12 +2694,13 @@ async def notify_internal_event(sdk_internal_event, event_metadata): async def test_track_async(self, mocker): """Test that destroy/destroyed calls are forwarded to the factory.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass events_manager.notify_internal_event = notify_internal_event - split_storage = InMemorySplitStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() segment_storage = mocker.Mock(spec=SegmentStorage) rb_segment_storage = mocker.Mock(spec=RuleBasedSegmentsStorage) impression_storage = mocker.Mock(spec=ImpressionStorage) @@ -2691,7 +2726,7 @@ async def put(event): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2720,6 +2755,7 @@ async def synchronize_config(*_): @pytest.mark.asyncio async def test_telemetry_not_ready_async(self, mocker): internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2727,9 +2763,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = InMemoryEventStorageAsync(10, telemetry_runtime_producer) @@ -2744,7 +2780,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': mocker.Mock()}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2771,6 +2807,7 @@ async def synchronize_config(*_): @pytest.mark.asyncio async def test_telemetry_record_treatment_exception_async(self, mocker): internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2778,9 +2815,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = InMemoryEventStorageAsync(10, telemetry_runtime_producer) @@ -2801,7 +2838,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2853,6 +2890,7 @@ def _raise(*_): @pytest.mark.asyncio async def test_telemetry_method_latency_async(self, mocker): internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -2860,9 +2898,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = InMemoryEventStorageAsync(10, telemetry_runtime_producer) @@ -2883,7 +2921,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2936,12 +2974,13 @@ async def synchronize_config(*_): @pytest.mark.asyncio async def test_telemetry_track_exception_async(self, mocker): internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass events_manager.notify_internal_event = notify_internal_event - split_storage = InMemorySplitStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() segment_storage = mocker.Mock(spec=SegmentStorage) rb_segment_storage = mocker.Mock(spec=RuleBasedSegmentsStorage) impression_storage = mocker.Mock(spec=ImpressionStorage) @@ -2964,7 +3003,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -2993,6 +3032,7 @@ async def exc(*_): async def test_impressions_properties_async(self, mocker): """Test get_treatment_async execution paths.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -3000,9 +3040,9 @@ async def notify_internal_event(sdk_internal_event, event_metadata): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) @@ -3027,7 +3067,7 @@ async def synchronize_config(*_): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, mocker.Mock(), telemetry_producer, @@ -3110,6 +3150,7 @@ async def synchronize_config(*_): async def test_fallback_treatment_eval_exception(self, mocker): # using fallback when the evaluator has RuntimeError exception internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -3147,7 +3188,7 @@ async def synchronize_config(*_): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, impmanager, telemetry_producer, @@ -3277,6 +3318,7 @@ async def fetch_many_rbs(*_): async def test_fallback_treatment_exception(self, mocker): # using fallback when the evaluator has RuntimeError exception internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -3310,7 +3352,7 @@ async def notify_internal_event(sdk_internal_event, event_metadata): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, impmanager, telemetry_producer, @@ -3381,6 +3423,7 @@ async def context_for(*_): async def test_fallback_treatment_not_ready_impressions(self, mocker): # using fallback when the evaluator has RuntimeError exception internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = mocker.Mock(EventsManagerAsync) async def notify_internal_event(sdk_internal_event, event_metadata): pass @@ -3414,7 +3457,7 @@ async def manager_start_task(): 'events': event_storage}, mocker.Mock(), recorder, - internal_events_queue, + events_emitter, events_manager, impmanager, telemetry_producer, diff --git a/tests/client/test_factory.py b/tests/client/test_factory.py index 054bd7ac..ba52de52 100644 --- a/tests/client/test_factory.py +++ b/tests/client/test_factory.py @@ -25,6 +25,7 @@ from splitio_commons.models.fallback_config import FallbackTreatmentsConfiguration, FallbackTreatmentCalculator from splitio_commons.models.fallback_treatment import FallbackTreatment from splitio_commons.models.events import SdkInternalEvent +from splitio.events.events_emitter import EventsEmitter from splitio_commons.recorder.recorder import PipelinedRecorder, StandardRecorder, StandardRecorderAsync from splitio_commons.storage import inmemmory, EventStorage from splitio.storage import inmemory, redis, pluggable @@ -45,163 +46,6 @@ class SplitFactoryTests(object): """Split factory test cases.""" - def test_flag_sets_counts(self): - factory = get_factory("none", config={ - 'flagSetsFilter': ['set1', 'set2', 'set3'] - }) - - assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets == 3 - assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets_invalid == 0 - event = threading.Event() - factory.destroy(event) -# event.wait() - - factory = get_factory("none", config={ - 'flagSetsFilter': ['s#et1', 'set2', 'set3'] - }) - assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets == 3 - assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets_invalid == 1 - event = threading.Event() - factory.destroy(event) -# event.wait() - - factory = get_factory("none", config={ - 'flagSetsFilter': ['s#et1', 22, 'set3'] - }) - assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets == 3 - assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets_invalid == 2 - event = threading.Event() - factory.destroy(event) -# event.wait() - - def test_inmemory_client_creation_streaming_false(self, mocker): - """Test that a client with in-memory storage is created correctly.""" - # Setup synchronizer - def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk_matadata, telemetry_runtime_producer, sse_url=None, client_key=None, push_manager=None, push_queue=None): - synchronizer = mocker.Mock(spec=Synchronizer) - synchronizer.sync_all.return_values = None - self._ready_flag = ready_flag - self._synchronizer = synchronizer - self._streaming_enabled = False - self._telemetry_runtime_producer = telemetry_runtime_producer - - mocker.patch('splitio_commons.sync.manager.Manager.__init__', new=_split_synchronizer) - - # Start factory and make assertions - factory = get_factory('some_api_key') - class TelemetrySubmitterMock(): - def synchronize_config(*_): - pass - factory._telemetry_submitter = TelemetrySubmitterMock() - - assert isinstance(factory._storages['splits'], inmemory.InMemorySplitStorage) - assert isinstance(factory._storages['segments'], inmemmory.InMemorySegmentStorage) - assert isinstance(factory._storages['impressions'], inmemmory.InMemoryImpressionStorage) - assert factory._storages['impressions']._impressions.maxsize == 10000 - assert isinstance(factory._storages['events'], inmemmory.InMemoryEventStorage) - assert factory._storages['events']._events.maxsize == 10000 - - assert isinstance(factory._sync_manager, Manager) - assert isinstance(factory._recorder, StandardRecorder) - assert isinstance(factory._recorder._impressions_manager, ImpressionsManager) - assert isinstance(factory._recorder._event_sotrage, inmemmory.EventStorage) - assert isinstance(factory._recorder._impression_storage, inmemmory.ImpressionStorage) - - assert factory._labels_enabled is True - try: - factory.block_until_ready(1) - except: - pass - assert factory.ready - factory.destroy() - - def test_redis_client_creation(self, mocker): - """Test that a client with redis storage is created correctly.""" - strict_redis_mock = mocker.Mock() - mocker.patch('splitio.storage.adapters.redis.StrictRedis', new=strict_redis_mock) - fallback_treatments_configuration = FallbackTreatmentsConfiguration(FallbackTreatment("on")) - config = { - 'labelsEnabled': False, - 'impressionListener': 123, - 'redisHost': 'some_host', - 'redisPort': 1234, - 'redisDb': 1, - 'redisPassword': 'some_password', - 'redisUsername': 'redis_user', - 'redisSocketTimeout': 123, - 'redisSocketConnectTimeout': 123, - 'redisSocketKeepalive': 123, - 'redisSocketKeepaliveOptions': False, - 'redisConnectionPool': False, - 'redisUnixSocketPath': '/some_path', - 'redisEncodingErrors': 'non-strict', - 'redisDecodeResponses': True, - 'redisRetryOnTimeout': True, - 'redisSsl': True, - 'redisSslKeyfile': 'some_file', - 'redisSslCertfile': 'some_cert_file', - 'redisSslCertReqs': 'some_cert_req', - 'redisSslCaCerts': 'some_ca_cert', - 'redisMaxConnections': 999, - 'flagSetsFilter': ['set_1'], - 'fallbackTreatments': fallback_treatments_configuration - } - factory = get_factory('some_api_key', config=config) - class TelemetrySubmitterMock(): - def synchronize_config(*_): - pass - factory._telemetry_submitter = TelemetrySubmitterMock() - - assert isinstance(factory._get_storage('splits'), redis.RedisSplitStorage) - assert isinstance(factory._get_storage('segments'), redis.RedisSegmentStorage) - assert isinstance(factory._get_storage('impressions'), redis.RedisImpressionsStorage) - assert isinstance(factory._get_storage('events'), redis.RedisEventsStorage) - - assert factory._get_storage('splits').flag_set_filter.flag_sets == set([]) - assert factory._fallback_treatment_calculator.fallback_treatments_configuration.global_fallback_treatment.treatment == fallback_treatments_configuration.global_fallback_treatment.treatment - - adapter = factory._get_storage('splits')._redis - assert adapter == factory._get_storage('segments')._redis - assert adapter == factory._get_storage('impressions')._redis - assert adapter == factory._get_storage('events')._redis - - assert strict_redis_mock.mock_calls[0] == mocker.call( - host='some_host', - port=1234, - db=1, - username='redis_user', - password='some_password', - socket_timeout=123, - socket_connect_timeout=123, - socket_keepalive=123, - socket_keepalive_options=False, - connection_pool=False, - unix_socket_path='/some_path', - encoding='utf-8', - encoding_errors='non-strict', - decode_responses=True, - retry_on_timeout=True, - ssl=True, - ssl_keyfile='some_file', - ssl_certfile='some_cert_file', - ssl_cert_reqs='some_cert_req', - ssl_ca_certs='some_ca_cert', - max_connections=999, - ) - assert factory._labels_enabled is False - assert isinstance(factory._recorder, PipelinedRecorder) - assert isinstance(factory._recorder._impressions_manager, ImpressionsManager) - assert isinstance(factory._recorder._make_pipe(), RedisPipelineAdapter) - assert isinstance(factory._recorder._event_sotrage, redis.RedisEventsStorage) - assert isinstance(factory._recorder._impression_storage, redis.RedisImpressionsStorage) - - try: - factory.block_until_ready(1) - except: - pass - assert factory.ready - factory.destroy() - def test_destroy(self, mocker): """Test that tasks are shutdown and data is flushed when destroy is called.""" @@ -260,7 +104,7 @@ def _telemetry_task_init_mock(self, synchronize_telemetry, synchronize_telemetry new=_telemetry_task_init_mock) split_sync = mocker.Mock(spec=SplitSynchronizer) - split_sync.synchronize_definitions.return_value = [] + split_sync.synchronize_definitions.return_value = [], {}, False segment_sync = mocker.Mock(spec=SegmentSynchronizer) segment_sync.synchronize_segments.return_values = None syncs = HarnessSynchronizers(split_sync, segment_sync, mocker.Mock(), @@ -270,7 +114,7 @@ def _telemetry_task_init_mock(self, synchronize_telemetry, synchronize_telemetry # Setup synchronizer def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk_matadata, telemetry_runtime_producer, sse_url=None, client_key=None, push_manager=None, push_queue=None): - synchronizer = Synchronizer(syncs, tasks) + synchronizer = Synchronizer(syncs, tasks, EventsEmitter(queue.Queue())) self._ready_flag = ready_flag self._synchronizer = synchronizer self._streaming_enabled = False @@ -365,7 +209,7 @@ def _telemetry_task_init_mock(self, synchronize_telemetry, synchronize_telemetry internal_event_task_mock.start.side_effect = stop_mock_2 split_sync = mocker.Mock(spec=SplitSynchronizer) - split_sync.synchronize_definitions.return_value = [] + split_sync.synchronize_definitions.return_value = [], {}, False segment_sync = mocker.Mock(spec=SegmentSynchronizer) segment_sync.synchronize_segments.return_values = None syncs = HarnessSynchronizers(split_sync, segment_sync, mocker.Mock(), @@ -375,7 +219,7 @@ def _telemetry_task_init_mock(self, synchronize_telemetry, synchronize_telemetry # Setup synchronizer def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk_matadata, telemetry_runtime_producer, sse_url=None, client_key=None, push_manager=None, push_queue=None): - synchronizer = Synchronizer(syncs, tasks) + synchronizer = Synchronizer(syncs, tasks, EventsEmitter(queue.Queue())) self._ready_flag = ready_flag self._synchronizer = synchronizer self._streaming_enabled = False @@ -404,6 +248,163 @@ def synchronize_config(*_): assert len(evt_async_task_mock.stop.mock_calls) == 1 assert len(imp_count_async_task_mock.stop.mock_calls) == 1 assert factory.destroyed is True + + def test_flag_sets_counts(self): + factory = get_factory("none", config={ + 'flagSetsFilter': ['set1', 'set2', 'set3'] + }) + + assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets == 3 + assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets_invalid == 0 + event = threading.Event() + factory.destroy(event) +# event.wait() + + factory = get_factory("none", config={ + 'flagSetsFilter': ['s#et1', 'set2', 'set3'] + }) + assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets == 3 + assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets_invalid == 1 + event = threading.Event() + factory.destroy(event) +# event.wait() + + factory = get_factory("none", config={ + 'flagSetsFilter': ['s#et1', 22, 'set3'] + }) + assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets == 3 + assert factory._telemetry_init_producer._telemetry_storage._tel_config._flag_sets_invalid == 2 + event = threading.Event() + factory.destroy(event) +# event.wait() + + def test_inmemory_client_creation_streaming_false(self, mocker): + """Test that a client with in-memory storage is created correctly.""" + # Setup synchronizer + def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk_matadata, telemetry_runtime_producer, sse_url=None, client_key=None, push_manager=None, push_queue=None): + synchronizer = mocker.Mock(spec=Synchronizer) + synchronizer.sync_all.return_values = None + self._ready_flag = ready_flag + self._synchronizer = synchronizer + self._streaming_enabled = False + self._telemetry_runtime_producer = telemetry_runtime_producer + + mocker.patch('splitio_commons.sync.manager.Manager.__init__', new=_split_synchronizer) + + # Start factory and make assertions + factory = get_factory('some_api_key') + class TelemetrySubmitterMock(): + def synchronize_config(*_): + pass + factory._telemetry_submitter = TelemetrySubmitterMock() + + assert isinstance(factory._storages['splits'], inmemory.InMemorySplitStorage) + assert isinstance(factory._storages['segments'], inmemmory.InMemorySegmentStorage) + assert isinstance(factory._storages['impressions'], inmemmory.InMemoryImpressionStorage) + assert factory._storages['impressions']._impressions.maxsize == 10000 + assert isinstance(factory._storages['events'], inmemmory.InMemoryEventStorage) + assert factory._storages['events']._events.maxsize == 10000 + + assert isinstance(factory._sync_manager, Manager) + assert isinstance(factory._recorder, StandardRecorder) + assert isinstance(factory._recorder._impressions_manager, ImpressionsManager) + assert isinstance(factory._recorder._event_sotrage, inmemmory.EventStorage) + assert isinstance(factory._recorder._impression_storage, inmemmory.ImpressionStorage) + + assert factory._labels_enabled is True + try: + factory.block_until_ready(1) + except: + pass + assert factory.ready + factory.destroy() + + def test_redis_client_creation(self, mocker): + """Test that a client with redis storage is created correctly.""" + strict_redis_mock = mocker.Mock() + mocker.patch('splitio.storage.adapters.redis.StrictRedis', new=strict_redis_mock) + fallback_treatments_configuration = FallbackTreatmentsConfiguration(FallbackTreatment("on")) + config = { + 'labelsEnabled': False, + 'impressionListener': 123, + 'redisHost': 'some_host', + 'redisPort': 1234, + 'redisDb': 1, + 'redisPassword': 'some_password', + 'redisUsername': 'redis_user', + 'redisSocketTimeout': 123, + 'redisSocketConnectTimeout': 123, + 'redisSocketKeepalive': 123, + 'redisSocketKeepaliveOptions': False, + 'redisConnectionPool': False, + 'redisUnixSocketPath': '/some_path', + 'redisEncodingErrors': 'non-strict', + 'redisDecodeResponses': True, + 'redisRetryOnTimeout': True, + 'redisSsl': True, + 'redisSslKeyfile': 'some_file', + 'redisSslCertfile': 'some_cert_file', + 'redisSslCertReqs': 'some_cert_req', + 'redisSslCaCerts': 'some_ca_cert', + 'redisMaxConnections': 999, + 'flagSetsFilter': ['set_1'], + 'fallbackTreatments': fallback_treatments_configuration + } + factory = get_factory('some_api_key', config=config) + class TelemetrySubmitterMock(): + def synchronize_config(*_): + pass + factory._telemetry_submitter = TelemetrySubmitterMock() + + assert isinstance(factory._get_storage('splits'), redis.RedisSplitStorage) + assert isinstance(factory._get_storage('segments'), redis.RedisSegmentStorage) + assert isinstance(factory._get_storage('impressions'), redis.RedisImpressionsStorage) + assert isinstance(factory._get_storage('events'), redis.RedisEventsStorage) + + assert factory._get_storage('splits').flag_set_filter.flag_sets == set([]) + assert factory._fallback_treatment_calculator.fallback_treatments_configuration.global_fallback_treatment.treatment == fallback_treatments_configuration.global_fallback_treatment.treatment + + adapter = factory._get_storage('splits')._redis + assert adapter == factory._get_storage('segments')._redis + assert adapter == factory._get_storage('impressions')._redis + assert adapter == factory._get_storage('events')._redis + + assert strict_redis_mock.mock_calls[0] == mocker.call( + host='some_host', + port=1234, + db=1, + username='redis_user', + password='some_password', + socket_timeout=123, + socket_connect_timeout=123, + socket_keepalive=123, + socket_keepalive_options=False, + connection_pool=False, + unix_socket_path='/some_path', + encoding='utf-8', + encoding_errors='non-strict', + decode_responses=True, + retry_on_timeout=True, + ssl=True, + ssl_keyfile='some_file', + ssl_certfile='some_cert_file', + ssl_cert_reqs='some_cert_req', + ssl_ca_certs='some_ca_cert', + max_connections=999, + ) + assert factory._labels_enabled is False + assert isinstance(factory._recorder, PipelinedRecorder) + assert isinstance(factory._recorder._impressions_manager, ImpressionsManager) + assert isinstance(factory._recorder._make_pipe(), RedisPipelineAdapter) + assert isinstance(factory._recorder._event_sotrage, redis.RedisEventsStorage) + assert isinstance(factory._recorder._impression_storage, redis.RedisImpressionsStorage) + + try: + factory.block_until_ready(1) + except: + pass + assert factory.ready + factory.destroy() def test_destroy_with_event_redis(self, mocker): def _make_factory_with_apikey(apikey, *_, **__): @@ -729,9 +730,10 @@ def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() impression_storage = InMemoryImpressionStorage(10000, telemetry_runtime_producer) impmanager = ImpressionsManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) @@ -748,7 +750,7 @@ def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk 'events': event_storage}, mocker.Mock(), recorder, - events_queue, + events_emitter, mocker.Mock(), mocker.Mock(), mocker.Mock(), @@ -941,8 +943,8 @@ def _telemetry_task_init_mock(self, synchronize_telemetry, synchronize_telemetry new=_telemetry_task_init_mock) split_sync = mocker.Mock(spec=SplitSynchronizerAsync) - async def synchronize_splits(*_): - return [] + async def synchronize_splits(till=None, rbs_till=None, emit_event=True): + return [], {}, False split_sync.synchronize_definitions = synchronize_splits segment_sync = mocker.Mock(spec=SegmentSynchronizerAsync) @@ -957,7 +959,7 @@ async def synchronize_segments(*_): # Setup synchronizer def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk_matadata, telemetry_runtime_producer, sse_url=None, client_key=None, push_manager=None, push_queue=None): - synchronizer = SynchronizerAsync(syncs, tasks) + synchronizer = SynchronizerAsync(syncs, tasks, EventsEmitter(queue.Queue())) self._ready_flag = ready_flag self._synchronizer = synchronizer self._streaming_enabled = False @@ -1109,7 +1111,7 @@ async def record_active_and_redundant_factories(*_): except: pass await asyncio.sleep(.2) - event = await factory._internal_events_queue.get() + event = await factory._events_emitter._internal_event_queue.get() assert event.internal_event == SdkInternalEvent.SDK_READY assert event.metadata == None await factory.destroy() \ No newline at end of file diff --git a/tests/client/test_manager.py b/tests/client/test_manager.py index e0f4d6cc..1b4a9b5a 100644 --- a/tests/client/test_manager.py +++ b/tests/client/test_manager.py @@ -20,7 +20,7 @@ def test_manager_calls(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) events_queue = queue.Queue() - storage = InMemorySplitStorage(events_queue) + storage = InMemorySplitStorage() factory = mocker.Mock(spec=SplitFactory) factory._storages = {'split': storage} @@ -95,7 +95,7 @@ async def test_manager_calls(self, mocker): internal_events_queue = asyncio.Queue() telemetry_storage = InMemoryTelemetryStorageAsync() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) - storage = InMemorySplitStorageAsync(internal_events_queue) + storage = InMemorySplitStorageAsync() factory = mocker.Mock(spec=SplitFactory) factory._storages = {'split': storage} diff --git a/tests/integration/test_client_e2e.py b/tests/integration/test_client_e2e.py index 8fd96a12..d59d7b53 100644 --- a/tests/integration/test_client_e2e.py +++ b/tests/integration/test_client_e2e.py @@ -37,6 +37,7 @@ from splitio_commons.models.events import SdkEvent from splitio_commons.models.fallback_config import FallbackTreatmentsConfiguration, FallbackTreatmentCalculator from splitio_commons.models.fallback_treatment import FallbackTreatment +from splitio.events.events_emitter import EventsEmitter from splitio_commons.recorder.recorder import StandardRecorder, PipelinedRecorder, StandardRecorderAsync, PipelinedRecorderAsync from splitio.storage.inmemory import InMemorySplitStorage, InMemorySplitStorageAsync from splitio_commons.storage.inmemmory import InMemoryEventStorage, InMemoryImpressionStorage, \ @@ -533,9 +534,10 @@ class InMemoryDebugIntegrationTests(object): def setup_method(self): """Prepare storages with test data.""" events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() split_fn = os.path.join(os.path.dirname(__file__), 'files', 'splitChanges.json') with open(split_fn, 'r') as flo: @@ -579,7 +581,7 @@ def setup_method(self): storages, True, recorder, - events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -702,9 +704,10 @@ class InMemoryOptimizedIntegrationTests(object): def setup_method(self): """Prepare storages with test data.""" events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() split_fn = os.path.join(os.path.dirname(__file__), 'files', 'splitChanges.json') with open(split_fn, 'r') as flo: data = json.loads(flo.read()) @@ -744,7 +747,7 @@ def setup_method(self): storages, True, recorder, - events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -1043,11 +1046,12 @@ def setup_method(self): storages['impressions'], telemetry_redis_storage, imp_counter=ImpressionsCounter()) events_manager = EventsManager(EventsManagerConfig(), EventsDelivery()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) self.factory = SplitFactory('some_api_key', storages, True, recorder, - events_queue, + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -1236,11 +1240,12 @@ def setup_method(self): storages['events'], storages['impressions'], telemetry_redis_storage, imp_counter=ImpressionsCounter()) events_manager = EventsManager(EventsManagerConfig(), EventsDelivery()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) self.factory = SplitFactory('some_api_key', storages, True, recorder, - events_queue, + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -1483,11 +1488,12 @@ def setup_method(self): events_manager = EventsManager(EventsManagerConfig(), EventsDelivery()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) self.factory = SplitFactory('some_api_key', storages, True, recorder, - events_queue, + events_emitter, events_manager, RedisManager(PluggableSynchronizer()), sdk_ready_flag=None, @@ -1683,11 +1689,12 @@ def setup_method(self): events_manager = EventsManager(EventsManagerConfig(), EventsDelivery()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) self.factory = SplitFactory('some_api_key', storages, True, recorder, - events_queue, + events_emitter, events_manager, RedisManager(PluggableSynchronizer()), sdk_ready_flag=None, @@ -1882,11 +1889,12 @@ def setup_method(self): manager.start() events_manager = EventsManager(EventsManagerConfig(), EventsDelivery()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) self.factory = SplitFactory('some_api_key', storages, True, recorder, - events_queue, + events_emitter, events_manager, manager, sdk_ready_flag=None, @@ -2016,8 +2024,9 @@ class InMemoryImpressionsToggleIntegrationTests(object): def test_optimized(self): events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() split_storage.update([splits.from_raw(splits_json['splitChange1_1']['ff']['d'][0]), splits.from_raw(splits_json['splitChange1_1']['ff']['d'][1]), @@ -2032,7 +2041,7 @@ def test_optimized(self): storages = { 'splits': split_storage, 'segments': segment_storage, - 'rule_based_segments': InMemoryRuleBasedSegmentStorage(events_queue), + 'rule_based_segments': InMemoryRuleBasedSegmentStorage(), 'impressions': InMemoryImpressionStorage(50000, telemetry_runtime_producer), 'events': InMemoryEventStorage(50000, telemetry_runtime_producer), } @@ -2045,7 +2054,7 @@ def test_optimized(self): storages, True, recorder, - events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -2078,8 +2087,9 @@ def test_optimized(self): def test_debug(self): events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() split_storage.update([splits.from_raw(splits_json['splitChange1_1']['ff']['d'][0]), splits.from_raw(splits_json['splitChange1_1']['ff']['d'][1]), @@ -2094,7 +2104,7 @@ def test_debug(self): storages = { 'splits': split_storage, 'segments': segment_storage, - 'rule_based_segments': InMemoryRuleBasedSegmentStorage(events_queue), + 'rule_based_segments': InMemoryRuleBasedSegmentStorage(), 'impressions': InMemoryImpressionStorage(50000, telemetry_runtime_producer), 'events': InMemoryEventStorage(50000, telemetry_runtime_producer), } @@ -2108,7 +2118,7 @@ def test_debug(self): storages, True, recorder, - events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -2142,8 +2152,9 @@ def test_debug(self): def test_none(self): events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() split_storage.update([splits.from_raw(splits_json['splitChange1_1']['ff']['d'][0]), splits.from_raw(splits_json['splitChange1_1']['ff']['d'][1]), @@ -2158,7 +2169,7 @@ def test_none(self): storages = { 'splits': split_storage, 'segments': segment_storage, - 'rule_based_segments': InMemoryRuleBasedSegmentStorage(events_queue), + 'rule_based_segments': InMemoryRuleBasedSegmentStorage(), 'impressions': InMemoryImpressionStorage(50000, telemetry_runtime_producer), 'events': InMemoryEventStorage(50000, telemetry_runtime_producer), } @@ -2172,8 +2183,8 @@ def test_none(self): storages, True, recorder, - events_queue, - events_queue, + events_emitter, + events_manager, None, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -2238,11 +2249,12 @@ def test_optimized(self): storages['events'], storages['impressions'], telemetry_redis_storage, unique_keys_tracker=UniqueKeysTracker(), imp_counter=ImpressionsCounter()) events_manager = EventsManager(EventsManagerConfig(), EventsDelivery()) events_queue = queue.Queue() + events_emitter = EventsEmitter(events_queue) factory = SplitFactory('some_api_key', storages, True, recorder, - events_queue, + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -2308,11 +2320,12 @@ def test_debug(self): recorder = PipelinedRecorder(redis_client.pipeline, impmanager, storages['events'], storages['impressions'], telemetry_redis_storage, unique_keys_tracker=UniqueKeysTracker(), imp_counter=ImpressionsCounter()) events_manager = EventsManager(EventsManagerConfig(), EventsDelivery()) + events_emitter = EventsEmitter(queue.Queue()) factory = SplitFactory('some_api_key', storages, True, recorder, - queue.Queue(), + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -2382,7 +2395,7 @@ def test_none(self): storages, True, recorder, - queue.Queue(), + EventsEmitter(queue.Queue()), events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -2445,9 +2458,10 @@ class InMemoryEventsNotificationTests(object): def test_sdk_ready(self): """Prepare storages with test data.""" events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() split_fn = os.path.join(os.path.dirname(__file__), 'files', 'splitChanges.json') with open(split_fn, 'r') as flo: @@ -2491,7 +2505,7 @@ def test_sdk_ready(self): storages, True, recorder, - events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -2515,9 +2529,10 @@ def test_sdk_ready(self): def test_sdk_ready_fire_later(self): """Prepare storages with test data.""" events_queue = queue.Queue() - split_storage = InMemorySplitStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorage(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorage() + segment_storage = InMemorySegmentStorage() + rb_segment_storage = InMemoryRuleBasedSegmentStorage() split_fn = os.path.join(os.path.dirname(__file__), 'files', 'splitChanges.json') with open(split_fn, 'r') as flo: @@ -2561,7 +2576,7 @@ def test_sdk_ready_fire_later(self): storages, True, recorder, - events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -2599,9 +2614,10 @@ class InMemoryEventsNotificationAsyncTests(object): async def test_sdk_ready(self): """Prepare storages with test data.""" events_queue = asyncio.Queue() - split_storage = InMemorySplitStorageAsync(events_queue) - segment_storage = InMemorySegmentStorageAsync(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() split_fn = os.path.join(os.path.dirname(__file__), 'files', 'splitChanges.json') with open(split_fn, 'r') as flo: @@ -2645,7 +2661,7 @@ async def test_sdk_ready(self): storages, True, recorder, - events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -2669,9 +2685,10 @@ async def test_sdk_ready(self): async def test_sdk_ready_fire_later(self): """Prepare storages with test data.""" events_queue = asyncio.Queue() - split_storage = InMemorySplitStorageAsync(events_queue) - segment_storage = InMemorySegmentStorageAsync(events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(events_queue) + events_emitter = EventsEmitter(events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() split_fn = os.path.join(os.path.dirname(__file__), 'files', 'splitChanges.json') with open(split_fn, 'r') as flo: @@ -2715,7 +2732,7 @@ async def test_sdk_ready_fire_later(self): storages, True, recorder, - events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -2746,11 +2763,12 @@ def setup_method(self): async def _setup_method(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() split_fn = os.path.join(os.path.dirname(__file__), 'files', 'splitChanges.json') with open(split_fn, 'r') as flo: @@ -2791,7 +2809,7 @@ async def _setup_method(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -2923,11 +2941,12 @@ def setup_method(self): async def _setup_method(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) - rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() + rb_segment_storage = InMemoryRuleBasedSegmentStorageAsync() split_fn = os.path.join(os.path.dirname(__file__), 'files', 'splitChanges.json') with open(split_fn, 'r') as flo: data = json.loads(flo.read()) @@ -2968,7 +2987,7 @@ async def _setup_method(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -3273,6 +3292,7 @@ def setup_method(self): async def _setup_method(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name') @@ -3327,7 +3347,7 @@ async def _setup_method(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -3501,6 +3521,7 @@ def setup_method(self): async def _setup_method(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name') @@ -3555,7 +3576,7 @@ async def _setup_method(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -3566,7 +3587,6 @@ async def _setup_method(self): ready_property.return_value = True type(self.factory).ready = ready_property - class LocalhostIntegrationAsyncTests(object): # pylint: disable=too-few-public-methods """Client & Manager integration tests.""" @@ -3779,6 +3799,7 @@ def setup_method(self): async def _setup_method(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name') @@ -3811,7 +3832,7 @@ async def _setup_method(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, RedisManagerAsync(PluggableSynchronizerAsync()), telemetry_producer=telemetry_producer, @@ -4013,6 +4034,7 @@ def setup_method(self): async def _setup_method(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name') @@ -4046,7 +4068,7 @@ async def _setup_method(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, RedisManagerAsync(PluggableSynchronizerAsync()), telemetry_producer=telemetry_producer, @@ -4235,6 +4257,7 @@ def setup_method(self): async def _setup_method(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name') @@ -4288,7 +4311,7 @@ async def _setup_method(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, manager, telemetry_producer=telemetry_producer, @@ -4477,10 +4500,11 @@ class InMemoryImpressionsToggleIntegrationAsyncTests(object): @pytest.mark.asyncio async def test_optimized(self): internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() await split_storage.update([splits.from_raw(splits_json['splitChange1_1']['ff']['d'][0]), splits.from_raw(splits_json['splitChange1_1']['ff']['d'][1]), @@ -4495,7 +4519,7 @@ async def test_optimized(self): storages = { 'splits': split_storage, 'segments': segment_storage, - 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(internal_events_queue), + 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(), 'impressions': InMemoryImpressionStorageAsync(5000, telemetry_runtime_producer), 'events': InMemoryEventStorageAsync(5000, telemetry_runtime_producer), } @@ -4507,7 +4531,7 @@ async def test_optimized(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -4543,10 +4567,11 @@ async def test_optimized(self): @pytest.mark.asyncio async def test_debug(self): internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() await split_storage.update([splits.from_raw(splits_json['splitChange1_1']['ff']['d'][0]), splits.from_raw(splits_json['splitChange1_1']['ff']['d'][1]), @@ -4561,7 +4586,7 @@ async def test_debug(self): storages = { 'splits': split_storage, 'segments': segment_storage, - 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(internal_events_queue), + 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(), 'impressions': InMemoryImpressionStorageAsync(5000, telemetry_runtime_producer), 'events': InMemoryEventStorageAsync(5000, telemetry_runtime_producer), } @@ -4573,7 +4598,7 @@ async def test_debug(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -4609,10 +4634,11 @@ async def test_debug(self): @pytest.mark.asyncio async def test_none(self): internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) - split_storage = InMemorySplitStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) + split_storage = InMemorySplitStorageAsync() + segment_storage = InMemorySegmentStorageAsync() await split_storage.update([splits.from_raw(splits_json['splitChange1_1']['ff']['d'][0]), splits.from_raw(splits_json['splitChange1_1']['ff']['d'][1]), @@ -4627,7 +4653,7 @@ async def test_none(self): storages = { 'splits': split_storage, 'segments': segment_storage, - 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(internal_events_queue), + 'rule_based_segments': InMemoryRuleBasedSegmentStorageAsync(), 'impressions': InMemoryImpressionStorageAsync(5000, telemetry_runtime_producer), 'events': InMemoryEventStorageAsync(5000, telemetry_runtime_producer), } @@ -4639,7 +4665,7 @@ async def test_none(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, None, telemetry_producer=telemetry_producer, @@ -4680,6 +4706,7 @@ class RedisImpressionsToggleIntegrationAsyncTests(object): @pytest.mark.asyncio async def test_optimized(self): internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) """Prepare storages with test data.""" @@ -4713,7 +4740,7 @@ async def test_optimized(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -4756,6 +4783,7 @@ async def test_optimized(self): async def test_debug(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name') @@ -4788,7 +4816,7 @@ async def test_debug(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), @@ -4831,6 +4859,7 @@ async def test_debug(self): async def test_none(self): """Prepare storages with test data.""" internal_events_queue = asyncio.Queue() + events_emitter = EventsEmitter(internal_events_queue) events_manager = EventsManagerAsync(EventsManagerConfig(), EventsDelivery()) metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name') @@ -4863,7 +4892,7 @@ async def test_none(self): storages, True, recorder, - internal_events_queue, + events_emitter, events_manager, telemetry_producer=telemetry_producer, telemetry_init_producer=telemetry_producer.get_telemetry_init_producer(), diff --git a/tests/push/test_split_worker.py b/tests/push/test_split_worker.py index de7b6187..5c6ec76b 100644 --- a/tests/push/test_split_worker.py +++ b/tests/push/test_split_worker.py @@ -8,7 +8,7 @@ from splitio.push.workers import SplitWorker, SplitWorkerAsync from splitio_commons.models.notification import SplitChangeNotification from splitio_commons.optional.loaders import asyncio -from splitio_commons.push.parser import SplitChangeUpdate, RBSChangeUpdate +from splitio.push.models import SplitChangeUpdate, RBSChangeUpdate, EventUpdateType from splitio_commons.engine.telemetry import TelemetryStorageProducer, TelemetryStorageProducerAsync from splitio_commons.storage.inmemmory import InMemoryTelemetryStorage, InMemoryDefinitionStorage, InMemorySegmentStorage, \ InMemoryTelemetryStorageAsync, InMemoryDefinitionStorageAsync, InMemorySegmentStorageAsync @@ -67,7 +67,7 @@ class SplitWorkerTests(object): def test_handler(self, mocker): q = queue.Queue() - split_worker = SplitWorker(handler_sync, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) + split_worker = SplitWorker(handler_sync, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) global change_number_received global rbs_change_number_received @@ -104,38 +104,38 @@ def update(rbs_add, rbs_delete, change_number): rbs1 = rbs1.replace("'", "\"") rbs1 = rbs1.replace("False", "false") encoded = base64.b64encode(bytes(rbs1, "utf-8")) - q.put(RBSChangeUpdate('some', 'RB_SEGMENT_UPDATE', 123456790, 2345, encoded, 0)) + q.put(RBSChangeUpdate('some', 'RB_SEGMENT_UPDATE', 123456790, {'pcn': 2345, 'd': encoded, 'c': 0}, EventUpdateType)) time.sleep(0.1) assert rbs_change_number_received == 0 assert self._rbs_added[0].name == "sample_rule_based_segment" # should call the handler - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456789, None, None, None)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456789, {'pcn': None, 'd': None, 'c': None}, EventUpdateType)) time.sleep(0.1) assert change_number_received == 123456789 assert rbs_change_number_received == None # should call the handler - q.put(RBSChangeUpdate('some', 'RB_SEGMENT_UPDATE', 123456789, None, None, None)) + q.put(RBSChangeUpdate('some', 'RB_SEGMENT_UPDATE', 123456789, {'pcn': None, 'd': None, 'c': None}, EventUpdateType)) time.sleep(0.1) assert rbs_change_number_received == 123456789 assert change_number_received == None # should call the handler - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 12345, "{}", 1)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 12345, 'd': "{}", 'c': 1}, EventUpdateType)) time.sleep(0.1) assert change_number_received == 123456790 # should call the handler change_number_received = 0 - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 12345, "{}", 3)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 12345, 'd': "{}", 'c': 3}, EventUpdateType)) time.sleep(0.1) assert change_number_received == 123456790 # should Not call the handler change_number_received = 0 - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, 2345, "eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 2)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': 2345, 'd': "eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 'c': 2}, EventUpdateType)) time.sleep(0.1) assert change_number_received == 0 @@ -147,11 +147,11 @@ def test_on_error(self, mocker): def handler_sync(change_number): raise APIException('some') - split_worker = SplitWorker(handler_sync, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) + split_worker = SplitWorker(handler_sync, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) split_worker.start() assert split_worker.is_running() - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456789, None, None, None)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456789, {'pcn': None, 'd': None, 'c': None}, EventUpdateType)) with pytest.raises(Exception): split_worker._handler() @@ -167,7 +167,7 @@ def test_compression(self, mocker): telemetry_storage = InMemoryTelemetryStorage() telemetry_producer = TelemetryStorageProducer(telemetry_storage) telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() - split_worker = SplitWorker(handler_sync, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), telemetry_runtime_producer, mocker.Mock()) + split_worker = SplitWorker(handler_sync, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), telemetry_runtime_producer, mocker.Mock(), mocker.Mock()) global change_number_received split_worker.start() def get_change_number(): @@ -185,7 +185,7 @@ def update(feature_flag_add, feature_flag_delete, change_number): # compression 0 self._feature_flag_added = None self._feature_flag_deleted = None - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 2345, 'eyJ0cmFmZmljVHlwZU5hbWUiOiJ1c2VyIiwiaWQiOiIzM2VhZmE1MC0xYTY1LTExZWQtOTBkZi1mYTMwZDk2OTA0NDUiLCJuYW1lIjoiYmlsYWxfc3BsaXQiLCJ0cmFmZmljQWxsb2NhdGlvbiI6MTAwLCJ0cmFmZmljQWxsb2NhdGlvblNlZWQiOi0xMzY0MTE5MjgyLCJzZWVkIjotNjA1OTM4ODQzLCJzdGF0dXMiOiJBQ1RJVkUiLCJraWxsZWQiOmZhbHNlLCJkZWZhdWx0VHJlYXRtZW50Ijoib2ZmIiwiY2hhbmdlTnVtYmVyIjoxNjg0MzQwOTA4NDc1LCJhbGdvIjoyLCJjb25maWd1cmF0aW9ucyI6e30sImNvbmRpdGlvbnMiOlt7ImNvbmRpdGlvblR5cGUiOiJST0xMT1VUIiwibWF0Y2hlckdyb3VwIjp7ImNvbWJpbmVyIjoiQU5EIiwibWF0Y2hlcnMiOlt7ImtleVNlbGVjdG9yIjp7InRyYWZmaWNUeXBlIjoidXNlciJ9LCJtYXRjaGVyVHlwZSI6IklOX1NFR01FTlQiLCJuZWdhdGUiOmZhbHNlLCJ1c2VyRGVmaW5lZFNlZ21lbnRNYXRjaGVyRGF0YSI6eyJzZWdtZW50TmFtZSI6ImJpbGFsX3NlZ21lbnQifX1dfSwicGFydGl0aW9ucyI6W3sidHJlYXRtZW50Ijoib24iLCJzaXplIjowfSx7InRyZWF0bWVudCI6Im9mZiIsInNpemUiOjEwMH1dLCJsYWJlbCI6ImluIHNlZ21lbnQgYmlsYWxfc2VnbWVudCJ9LHsiY29uZGl0aW9uVHlwZSI6IlJPTExPVVQiLCJtYXRjaGVyR3JvdXAiOnsiY29tYmluZXIiOiJBTkQiLCJtYXRjaGVycyI6W3sia2V5U2VsZWN0b3IiOnsidHJhZmZpY1R5cGUiOiJ1c2VyIn0sIm1hdGNoZXJUeXBlIjoiQUxMX0tFWVMiLCJuZWdhdGUiOmZhbHNlfV19LCJwYXJ0aXRpb25zIjpbeyJ0cmVhdG1lbnQiOiJvbiIsInNpemUiOjB9LHsidHJlYXRtZW50Ijoib2ZmIiwic2l6ZSI6MTAwfV0sImxhYmVsIjoiZGVmYXVsdCBydWxlIn1dfQ==', 0)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 2345, 'd': 'eyJ0cmFmZmljVHlwZU5hbWUiOiJ1c2VyIiwiaWQiOiIzM2VhZmE1MC0xYTY1LTExZWQtOTBkZi1mYTMwZDk2OTA0NDUiLCJuYW1lIjoiYmlsYWxfc3BsaXQiLCJ0cmFmZmljQWxsb2NhdGlvbiI6MTAwLCJ0cmFmZmljQWxsb2NhdGlvblNlZWQiOi0xMzY0MTE5MjgyLCJzZWVkIjotNjA1OTM4ODQzLCJzdGF0dXMiOiJBQ1RJVkUiLCJraWxsZWQiOmZhbHNlLCJkZWZhdWx0VHJlYXRtZW50Ijoib2ZmIiwiY2hhbmdlTnVtYmVyIjoxNjg0MzQwOTA4NDc1LCJhbGdvIjoyLCJjb25maWd1cmF0aW9ucyI6e30sImNvbmRpdGlvbnMiOlt7ImNvbmRpdGlvblR5cGUiOiJST0xMT1VUIiwibWF0Y2hlckdyb3VwIjp7ImNvbWJpbmVyIjoiQU5EIiwibWF0Y2hlcnMiOlt7ImtleVNlbGVjdG9yIjp7InRyYWZmaWNUeXBlIjoidXNlciJ9LCJtYXRjaGVyVHlwZSI6IklOX1NFR01FTlQiLCJuZWdhdGUiOmZhbHNlLCJ1c2VyRGVmaW5lZFNlZ21lbnRNYXRjaGVyRGF0YSI6eyJzZWdtZW50TmFtZSI6ImJpbGFsX3NlZ21lbnQifX1dfSwicGFydGl0aW9ucyI6W3sidHJlYXRtZW50Ijoib24iLCJzaXplIjowfSx7InRyZWF0bWVudCI6Im9mZiIsInNpemUiOjEwMH1dLCJsYWJlbCI6ImluIHNlZ21lbnQgYmlsYWxfc2VnbWVudCJ9LHsiY29uZGl0aW9uVHlwZSI6IlJPTExPVVQiLCJtYXRjaGVyR3JvdXAiOnsiY29tYmluZXIiOiJBTkQiLCJtYXRjaGVycyI6W3sia2V5U2VsZWN0b3IiOnsidHJhZmZpY1R5cGUiOiJ1c2VyIn0sIm1hdGNoZXJUeXBlIjoiQUxMX0tFWVMiLCJuZWdhdGUiOmZhbHNlfV19LCJwYXJ0aXRpb25zIjpbeyJ0cmVhdG1lbnQiOiJvbiIsInNpemUiOjB9LHsidHJlYXRtZW50Ijoib2ZmIiwic2l6ZSI6MTAwfV0sImxhYmVsIjoiZGVmYXVsdCBydWxlIn1dfQ==', 'c': 0}, EventUpdateType)) time.sleep(0.1) assert self._feature_flag_added[0].name == 'bilal_split' assert telemetry_storage._counters._update_from_sse['sp'] == 1 @@ -193,7 +193,7 @@ def update(feature_flag_add, feature_flag_delete, change_number): # compression 2 self._feature_flag_added = None self._feature_flag_deleted = None - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 2345, 'eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==', 2)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 2345, 'd': 'eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==', 'c': 2}, EventUpdateType)) time.sleep(0.1) assert self._feature_flag_added[0].name == 'bilal_split' assert telemetry_storage._counters._update_from_sse['sp'] == 2 @@ -201,7 +201,7 @@ def update(feature_flag_add, feature_flag_delete, change_number): # compression 1 self._feature_flag_added = None self._feature_flag_deleted = None - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 2345, 'H4sIAAkVZWQC/8WST0+DQBDFv0qzZ0ig/BF6a2xjGismUk2MaZopzOKmy9Isy0EbvrtDwbY2Xo233Tdv5se85cCMBs5FtvrYYwIlsglratTMYiKns+chcAgc24UwsF0Xczt2cm5z8Jw8DmPH9wPyqr5zKyTITb2XwpA4TJ5KWWVgRKXYxHWcX/QUkVi264W+68bjaGyxupdCJ4i9KPI9UgyYpibI9Ha1eJnT/J2QsnNxkDVaLEcOjTQrjWBKVIasFefky95BFZg05Zb2mrhh5I9vgsiL44BAIIuKTeiQVYqLotHHLyLOoT1quRjub4fztQuLxj89LpePzytClGCyd9R3umr21ErOcitUh2PTZHY29HN2+JGixMxUujNfvMB3+u2pY1AXySad3z3Mk46msACDp8W7jhly4uUpFt3qD33vDAx0gLpXkx+P1GusbdcE24M2F4uaywwVEWvxSa1Oa13Vjvn2RXradm0xCVuUVBJqNCBGV0DrX4OcLpeb+/lreh3jH8Uw/JQj3UhkxPgCCurdEnADAAA=', 1)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 2345, 'd': 'H4sIAAkVZWQC/8WST0+DQBDFv0qzZ0ig/BF6a2xjGismUk2MaZopzOKmy9Isy0EbvrtDwbY2Xo233Tdv5se85cCMBs5FtvrYYwIlsglratTMYiKns+chcAgc24UwsF0Xczt2cm5z8Jw8DmPH9wPyqr5zKyTITb2XwpA4TJ5KWWVgRKXYxHWcX/QUkVi264W+68bjaGyxupdCJ4i9KPI9UgyYpibI9Ha1eJnT/J2QsnNxkDVaLEcOjTQrjWBKVIasFefky95BFZg05Zb2mrhh5I9vgsiL44BAIIuKTeiQVYqLotHHLyLOoT1quRjub4fztQuLxj89LpePzytClGCyd9R3umr21ErOcitUh2PTZHY29HN2+JGixMxUujNfvMB3+u2pY1AXySad3z3Mk46msACDp8W7jhly4uUpFt3qD33vDAx0gLpXkx+P1GusbdcE24M2F4uaywwVEWvxSa1Oa13Vjvn2RXradm0xCVuUVBJqNCBGV0DrX4OcLpeb+/lreh3jH8Uw/JQj3UhkxPgCCurdEnADAAA=', 'c': 1}, EventUpdateType)) time.sleep(0.1) assert self._feature_flag_added[0].name == 'bilal_split' assert telemetry_storage._counters._update_from_sse['sp'] == 3 @@ -209,14 +209,14 @@ def update(feature_flag_add, feature_flag_delete, change_number): # should call delete split self._feature_flag_added = None self._feature_flag_deleted = None - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 2345, 'eyJ0cmFmZmljVHlwZU5hbWUiOiAidXNlciIsICJpZCI6ICIzM2VhZmE1MC0xYTY1LTExZWQtOTBkZi1mYTMwZDk2OTA0NDUiLCAibmFtZSI6ICJiaWxhbF9zcGxpdCIsICJ0cmFmZmljQWxsb2NhdGlvbiI6IDEwMCwgInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6IC0xMzY0MTE5MjgyLCAic2VlZCI6IC02MDU5Mzg4NDMsICJzdGF0dXMiOiAiQVJDSElWRUQiLCAia2lsbGVkIjogZmFsc2UsICJkZWZhdWx0VHJlYXRtZW50IjogIm9mZiIsICJjaGFuZ2VOdW1iZXIiOiAxNjg0Mjc1ODM5OTUyLCAiYWxnbyI6IDIsICJjb25maWd1cmF0aW9ucyI6IHt9LCAiY29uZGl0aW9ucyI6IFt7ImNvbmRpdGlvblR5cGUiOiAiUk9MTE9VVCIsICJtYXRjaGVyR3JvdXAiOiB7ImNvbWJpbmVyIjogIkFORCIsICJtYXRjaGVycyI6IFt7ImtleVNlbGVjdG9yIjogeyJ0cmFmZmljVHlwZSI6ICJ1c2VyIn0sICJtYXRjaGVyVHlwZSI6ICJJTl9TRUdNRU5UIiwgIm5lZ2F0ZSI6IGZhbHNlLCAidXNlckRlZmluZWRTZWdtZW50TWF0Y2hlckRhdGEiOiB7InNlZ21lbnROYW1lIjogImJpbGFsX3NlZ21lbnQifX1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDB9LCB7InRyZWF0bWVudCI6ICJvZmYiLCAic2l6ZSI6IDEwMH1dLCAibGFiZWwiOiAiaW4gc2VnbWVudCBiaWxhbF9zZWdtZW50In0sIHsiY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIifSwgIm1hdGNoZXJUeXBlIjogIkFMTF9LRVlTIiwgIm5lZ2F0ZSI6IGZhbHNlfV19LCAicGFydGl0aW9ucyI6IFt7InRyZWF0bWVudCI6ICJvbiIsICJzaXplIjogMH0sIHsidHJlYXRtZW50IjogIm9mZiIsICJzaXplIjogMTAwfV0sICJsYWJlbCI6ICJkZWZhdWx0IHJ1bGUifV19', 0)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 2345, 'd': 'eyJ0cmFmZmljVHlwZU5hbWUiOiAidXNlciIsICJpZCI6ICIzM2VhZmE1MC0xYTY1LTExZWQtOTBkZi1mYTMwZDk2OTA0NDUiLCAibmFtZSI6ICJiaWxhbF9zcGxpdCIsICJ0cmFmZmljQWxsb2NhdGlvbiI6IDEwMCwgInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6IC0xMzY0MTE5MjgyLCAic2VlZCI6IC02MDU5Mzg4NDMsICJzdGF0dXMiOiAiQVJDSElWRUQiLCAia2lsbGVkIjogZmFsc2UsICJkZWZhdWx0VHJlYXRtZW50IjogIm9mZiIsICJjaGFuZ2VOdW1iZXIiOiAxNjg0Mjc1ODM5OTUyLCAiYWxnbyI6IDIsICJjb25maWd1cmF0aW9ucyI6IHt9LCAiY29uZGl0aW9ucyI6IFt7ImNvbmRpdGlvblR5cGUiOiAiUk9MTE9VVCIsICJtYXRjaGVyR3JvdXAiOiB7ImNvbWJpbmVyIjogIkFORCIsICJtYXRjaGVycyI6IFt7ImtleVNlbGVjdG9yIjogeyJ0cmFmZmljVHlwZSI6ICJ1c2VyIn0sICJtYXRjaGVyVHlwZSI6ICJJTl9TRUdNRU5UIiwgIm5lZ2F0ZSI6IGZhbHNlLCAidXNlckRlZmluZWRTZWdtZW50TWF0Y2hlckRhdGEiOiB7InNlZ21lbnROYW1lIjogImJpbGFsX3NlZ21lbnQifX1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDB9LCB7InRyZWF0bWVudCI6ICJvZmYiLCAic2l6ZSI6IDEwMH1dLCAibGFiZWwiOiAiaW4gc2VnbWVudCBiaWxhbF9zZWdtZW50In0sIHsiY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIifSwgIm1hdGNoZXJUeXBlIjogIkFMTF9LRVlTIiwgIm5lZ2F0ZSI6IGZhbHNlfV19LCAicGFydGl0aW9ucyI6IFt7InRyZWF0bWVudCI6ICJvbiIsICJzaXplIjogMH0sIHsidHJlYXRtZW50IjogIm9mZiIsICJzaXplIjogMTAwfV0sICJsYWJlbCI6ICJkZWZhdWx0IHJ1bGUifV19', 'c': 0}, EventUpdateType)) time.sleep(0.1) assert self._feature_flag_deleted[0] == 'bilal_split' assert self._feature_flag_added == [] def test_edge_cases(self, mocker): q = queue.Queue() - split_worker = SplitWorker(handler_sync, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) + split_worker = SplitWorker(handler_sync, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) global change_number_received split_worker.start() @@ -235,42 +235,41 @@ def update(feature_flag_add, feature_flag_delete, change_number): # should Not call the handler self._feature_flag_added = None change_number_received = 0 - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, 2345, "/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 2)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': 2345, 'd': "/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 'c': 2}, EventUpdateType)) time.sleep(0.1) assert self._feature_flag_added == None # should Not call the handler self._feature_flag = None change_number_received = 0 - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, 2345, "/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 4)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': 2345, 'd': "/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 'c': 4}, EventUpdateType)) time.sleep(0.1) assert self._feature_flag_added == None # should Not call the handler self._feature_flag = None change_number_received = 0 - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, None, 'eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==', 2)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': None, 'd': 'eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==', 'c': 2}, EventUpdateType)) time.sleep(0.1) assert self._feature_flag_added == None # should Not call the handler self._feature_flag = None change_number_received = 0 - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, 2345, None, 1)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': 2345, 'd': None, 'c': 1}, EventUpdateType)) time.sleep(0.1) assert self._feature_flag_added == None def test_fetch_segment(self, mocker): q = queue.Queue() - events_queue = queue.Queue() - split_storage = InMemoryDefinitionStorage(events_queue) - segment_storage = InMemorySegmentStorage(events_queue) + split_storage = InMemoryDefinitionStorage() + segment_storage = InMemorySegmentStorage() self.segment_name = None def segment_handler_sync(segment_name, change_number): self.segment_name = segment_name return - split_worker = SplitWorker(handler_sync, segment_handler_sync, q, mocker.Mock(), split_storage, segment_storage, mocker.Mock(), mocker.Mock()) + split_worker = SplitWorker(handler_sync, segment_handler_sync, q, mocker.Mock(), split_storage, segment_storage, mocker.Mock(), mocker.Mock(), mocker.Mock()) split_worker.start() def get_change_number(): @@ -281,7 +280,7 @@ def check_instant_ff_update(event): return True split_worker._check_instant_ff_update = check_instant_ff_update - q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 1675095324253, 2345, 'eyJjaGFuZ2VOdW1iZXIiOiAxNjc1MDk1MzI0MjUzLCAidHJhZmZpY1R5cGVOYW1lIjogInVzZXIiLCAibmFtZSI6ICJiaWxhbF9zcGxpdCIsICJ0cmFmZmljQWxsb2NhdGlvbiI6IDEwMCwgInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6IC0xMzY0MTE5MjgyLCAic2VlZCI6IC02MDU5Mzg4NDMsICJzdGF0dXMiOiAiQUNUSVZFIiwgImtpbGxlZCI6IGZhbHNlLCAiZGVmYXVsdFRyZWF0bWVudCI6ICJvZmYiLCAiYWxnbyI6IDIsICJjb25kaXRpb25zIjogW3siY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIiLCAiYXR0cmlidXRlIjogbnVsbH0sICJtYXRjaGVyVHlwZSI6ICJJTl9TRUdNRU5UIiwgIm5lZ2F0ZSI6IGZhbHNlLCAidXNlckRlZmluZWRTZWdtZW50TWF0Y2hlckRhdGEiOiB7InNlZ21lbnROYW1lIjogImJpbGFsX3NlZ21lbnQifSwgIndoaXRlbGlzdE1hdGNoZXJEYXRhIjogbnVsbCwgInVuYXJ5TnVtZXJpY01hdGNoZXJEYXRhIjogbnVsbCwgImJldHdlZW5NYXRjaGVyRGF0YSI6IG51bGwsICJkZXBlbmRlbmN5TWF0Y2hlckRhdGEiOiBudWxsLCAiYm9vbGVhbk1hdGNoZXJEYXRhIjogbnVsbCwgInN0cmluZ01hdGNoZXJEYXRhIjogbnVsbH1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDB9LCB7InRyZWF0bWVudCI6ICJvZmYiLCAic2l6ZSI6IDEwMH1dLCAibGFiZWwiOiAiaW4gc2VnbWVudCBiaWxhbF9zZWdtZW50In0sIHsiY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIiLCAiYXR0cmlidXRlIjogbnVsbH0sICJtYXRjaGVyVHlwZSI6ICJBTExfS0VZUyIsICJuZWdhdGUiOiBmYWxzZSwgInVzZXJEZWZpbmVkU2VnbWVudE1hdGNoZXJEYXRhIjogbnVsbCwgIndoaXRlbGlzdE1hdGNoZXJEYXRhIjogbnVsbCwgInVuYXJ5TnVtZXJpY01hdGNoZXJEYXRhIjogbnVsbCwgImJldHdlZW5NYXRjaGVyRGF0YSI6IG51bGwsICJkZXBlbmRlbmN5TWF0Y2hlckRhdGEiOiBudWxsLCAiYm9vbGVhbk1hdGNoZXJEYXRhIjogbnVsbCwgInN0cmluZ01hdGNoZXJEYXRhIjogbnVsbH1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDUwfSwgeyJ0cmVhdG1lbnQiOiAib2ZmIiwgInNpemUiOiA1MH1dLCAibGFiZWwiOiAiZGVmYXVsdCBydWxlIn1dLCAiY29uZmlndXJhdGlvbnMiOiB7fX0=', 0)) + q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 1675095324253, {'pcn': 2345, 'd': 'eyJjaGFuZ2VOdW1iZXIiOiAxNjc1MDk1MzI0MjUzLCAidHJhZmZpY1R5cGVOYW1lIjogInVzZXIiLCAibmFtZSI6ICJiaWxhbF9zcGxpdCIsICJ0cmFmZmljQWxsb2NhdGlvbiI6IDEwMCwgInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6IC0xMzY0MTE5MjgyLCAic2VlZCI6IC02MDU5Mzg4NDMsICJzdGF0dXMiOiAiQUNUSVZFIiwgImtpbGxlZCI6IGZhbHNlLCAiZGVmYXVsdFRyZWF0bWVudCI6ICJvZmYiLCAiYWxnbyI6IDIsICJjb25kaXRpb25zIjogW3siY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIiLCAiYXR0cmlidXRlIjogbnVsbH0sICJtYXRjaGVyVHlwZSI6ICJJTl9TRUdNRU5UIiwgIm5lZ2F0ZSI6IGZhbHNlLCAidXNlckRlZmluZWRTZWdtZW50TWF0Y2hlckRhdGEiOiB7InNlZ21lbnROYW1lIjogImJpbGFsX3NlZ21lbnQifSwgIndoaXRlbGlzdE1hdGNoZXJEYXRhIjogbnVsbCwgInVuYXJ5TnVtZXJpY01hdGNoZXJEYXRhIjogbnVsbCwgImJldHdlZW5NYXRjaGVyRGF0YSI6IG51bGwsICJkZXBlbmRlbmN5TWF0Y2hlckRhdGEiOiBudWxsLCAiYm9vbGVhbk1hdGNoZXJEYXRhIjogbnVsbCwgInN0cmluZ01hdGNoZXJEYXRhIjogbnVsbH1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDB9LCB7InRyZWF0bWVudCI6ICJvZmYiLCAic2l6ZSI6IDEwMH1dLCAibGFiZWwiOiAiaW4gc2VnbWVudCBiaWxhbF9zZWdtZW50In0sIHsiY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIiLCAiYXR0cmlidXRlIjogbnVsbH0sICJtYXRjaGVyVHlwZSI6ICJBTExfS0VZUyIsICJuZWdhdGUiOiBmYWxzZSwgInVzZXJEZWZpbmVkU2VnbWVudE1hdGNoZXJEYXRhIjogbnVsbCwgIndoaXRlbGlzdE1hdGNoZXJEYXRhIjogbnVsbCwgInVuYXJ5TnVtZXJpY01hdGNoZXJEYXRhIjogbnVsbCwgImJldHdlZW5NYXRjaGVyRGF0YSI6IG51bGwsICJkZXBlbmRlbmN5TWF0Y2hlckRhdGEiOiBudWxsLCAiYm9vbGVhbk1hdGNoZXJEYXRhIjogbnVsbCwgInN0cmluZ01hdGNoZXJEYXRhIjogbnVsbH1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDUwfSwgeyJ0cmVhdG1lbnQiOiAib2ZmIiwgInNpemUiOiA1MH1dLCAibGFiZWwiOiAiZGVmYXVsdCBydWxlIn1dLCAiY29uZmlndXJhdGlvbnMiOiB7fX0=', 'c': 0}, EventUpdateType)) time.sleep(0.1) assert self.segment_name == "bilal_segment" @@ -294,7 +293,7 @@ async def test_on_error(self, mocker): def handler_sync(change_number): raise APIException('some') - split_worker = SplitWorkerAsync(handler_async, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) + split_worker = SplitWorkerAsync(handler_async, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) split_worker.start() assert split_worker.is_running() @@ -322,7 +321,7 @@ def _worker_running(self): @pytest.mark.asyncio async def test_handler(self, mocker): q = asyncio.Queue() - split_worker = SplitWorkerAsync(handler_async, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) + split_worker = SplitWorkerAsync(handler_async, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) assert not split_worker.is_running() split_worker.start() @@ -333,7 +332,7 @@ async def test_handler(self, mocker): global rbs_change_number_received # should call the handler - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456789, None, None, None)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456789, {'pcn': None, 'd': None, 'c': None}, EventUpdateType)) await asyncio.sleep(0.1) assert change_number_received == 123456789 @@ -376,25 +375,25 @@ async def update_rbs(rbs_add, rbs_delete, change_number): rbs1 = rbs1.replace("'", "\"") rbs1 = rbs1.replace("False", "false") encoded = base64.b64encode(bytes(rbs1, "utf-8")) - await q.put(RBSChangeUpdate('some', 'RB_SEGMENT_UPDATE', 123456790, 2345, encoded, 0)) + await q.put(RBSChangeUpdate('some', 'RB_SEGMENT_UPDATE', 123456790, {'pcn': 2345, 'd': encoded, 'c': 0}, EventUpdateType)) await asyncio.sleep(0.1) assert rbs_change_number_received == 0 assert self._rbs_added[0].name == "sample_rule_based_segment" # should call the handler - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 12345, "{}", 1)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 12345, 'd': "{}", 'c': 1}, EventUpdateType)) await asyncio.sleep(0.1) assert change_number_received == 123456790 # should call the handler change_number_received = 0 - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 12345, "{}", 3)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 12345, 'd': "{}", 'c': 3}, EventUpdateType)) await asyncio.sleep(0.1) assert change_number_received == 123456790 # should Not call the handler change_number_received = 0 - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, 2345, "eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 2)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': 2345, 'd': "eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 'c': 2}, EventUpdateType)) await asyncio.sleep(0.5) assert change_number_received == 0 @@ -410,7 +409,7 @@ async def test_compression(self, mocker): telemetry_storage = await InMemoryTelemetryStorageAsync.create() telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() - split_worker = SplitWorkerAsync(handler_async, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), telemetry_runtime_producer, mocker.Mock()) + split_worker = SplitWorkerAsync(handler_async, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), telemetry_runtime_producer, mocker.Mock(), mocker.Mock()) global change_number_received split_worker.start() async def get_change_number(): @@ -440,21 +439,21 @@ async def contains(rbs): split_worker._rule_based_segment_storage.contains = contains # compression 0 - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 2345, 'eyJ0cmFmZmljVHlwZU5hbWUiOiJ1c2VyIiwiaWQiOiIzM2VhZmE1MC0xYTY1LTExZWQtOTBkZi1mYTMwZDk2OTA0NDUiLCJuYW1lIjoiYmlsYWxfc3BsaXQiLCJ0cmFmZmljQWxsb2NhdGlvbiI6MTAwLCJ0cmFmZmljQWxsb2NhdGlvblNlZWQiOi0xMzY0MTE5MjgyLCJzZWVkIjotNjA1OTM4ODQzLCJzdGF0dXMiOiJBQ1RJVkUiLCJraWxsZWQiOmZhbHNlLCJkZWZhdWx0VHJlYXRtZW50Ijoib2ZmIiwiY2hhbmdlTnVtYmVyIjoxNjg0MzQwOTA4NDc1LCJhbGdvIjoyLCJjb25maWd1cmF0aW9ucyI6e30sImNvbmRpdGlvbnMiOlt7ImNvbmRpdGlvblR5cGUiOiJST0xMT1VUIiwibWF0Y2hlckdyb3VwIjp7ImNvbWJpbmVyIjoiQU5EIiwibWF0Y2hlcnMiOlt7ImtleVNlbGVjdG9yIjp7InRyYWZmaWNUeXBlIjoidXNlciJ9LCJtYXRjaGVyVHlwZSI6IklOX1NFR01FTlQiLCJuZWdhdGUiOmZhbHNlLCJ1c2VyRGVmaW5lZFNlZ21lbnRNYXRjaGVyRGF0YSI6eyJzZWdtZW50TmFtZSI6ImJpbGFsX3NlZ21lbnQifX1dfSwicGFydGl0aW9ucyI6W3sidHJlYXRtZW50Ijoib24iLCJzaXplIjowfSx7InRyZWF0bWVudCI6Im9mZiIsInNpemUiOjEwMH1dLCJsYWJlbCI6ImluIHNlZ21lbnQgYmlsYWxfc2VnbWVudCJ9LHsiY29uZGl0aW9uVHlwZSI6IlJPTExPVVQiLCJtYXRjaGVyR3JvdXAiOnsiY29tYmluZXIiOiJBTkQiLCJtYXRjaGVycyI6W3sia2V5U2VsZWN0b3IiOnsidHJhZmZpY1R5cGUiOiJ1c2VyIn0sIm1hdGNoZXJUeXBlIjoiQUxMX0tFWVMiLCJuZWdhdGUiOmZhbHNlfV19LCJwYXJ0aXRpb25zIjpbeyJ0cmVhdG1lbnQiOiJvbiIsInNpemUiOjB9LHsidHJlYXRtZW50Ijoib2ZmIiwic2l6ZSI6MTAwfV0sImxhYmVsIjoiZGVmYXVsdCBydWxlIn1dfQ==', 0)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 2345, 'd': 'eyJ0cmFmZmljVHlwZU5hbWUiOiJ1c2VyIiwiaWQiOiIzM2VhZmE1MC0xYTY1LTExZWQtOTBkZi1mYTMwZDk2OTA0NDUiLCJuYW1lIjoiYmlsYWxfc3BsaXQiLCJ0cmFmZmljQWxsb2NhdGlvbiI6MTAwLCJ0cmFmZmljQWxsb2NhdGlvblNlZWQiOi0xMzY0MTE5MjgyLCJzZWVkIjotNjA1OTM4ODQzLCJzdGF0dXMiOiJBQ1RJVkUiLCJraWxsZWQiOmZhbHNlLCJkZWZhdWx0VHJlYXRtZW50Ijoib2ZmIiwiY2hhbmdlTnVtYmVyIjoxNjg0MzQwOTA4NDc1LCJhbGdvIjoyLCJjb25maWd1cmF0aW9ucyI6e30sImNvbmRpdGlvbnMiOlt7ImNvbmRpdGlvblR5cGUiOiJST0xMT1VUIiwibWF0Y2hlckdyb3VwIjp7ImNvbWJpbmVyIjoiQU5EIiwibWF0Y2hlcnMiOlt7ImtleVNlbGVjdG9yIjp7InRyYWZmaWNUeXBlIjoidXNlciJ9LCJtYXRjaGVyVHlwZSI6IklOX1NFR01FTlQiLCJuZWdhdGUiOmZhbHNlLCJ1c2VyRGVmaW5lZFNlZ21lbnRNYXRjaGVyRGF0YSI6eyJzZWdtZW50TmFtZSI6ImJpbGFsX3NlZ21lbnQifX1dfSwicGFydGl0aW9ucyI6W3sidHJlYXRtZW50Ijoib24iLCJzaXplIjowfSx7InRyZWF0bWVudCI6Im9mZiIsInNpemUiOjEwMH1dLCJsYWJlbCI6ImluIHNlZ21lbnQgYmlsYWxfc2VnbWVudCJ9LHsiY29uZGl0aW9uVHlwZSI6IlJPTExPVVQiLCJtYXRjaGVyR3JvdXAiOnsiY29tYmluZXIiOiJBTkQiLCJtYXRjaGVycyI6W3sia2V5U2VsZWN0b3IiOnsidHJhZmZpY1R5cGUiOiJ1c2VyIn0sIm1hdGNoZXJUeXBlIjoiQUxMX0tFWVMiLCJuZWdhdGUiOmZhbHNlfV19LCJwYXJ0aXRpb25zIjpbeyJ0cmVhdG1lbnQiOiJvbiIsInNpemUiOjB9LHsidHJlYXRtZW50Ijoib2ZmIiwic2l6ZSI6MTAwfV0sImxhYmVsIjoiZGVmYXVsdCBydWxlIn1dfQ==', 'c': 0}, EventUpdateType)) await asyncio.sleep(0.1) assert self._feature_flag_added[0].name == 'bilal_split' assert telemetry_storage._counters._update_from_sse['sp'] == 1 # compression 2 self._feature_flag_added = None - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 2345, 'eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==', 2)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 2345, 'd': 'eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==', 'c': 2}, EventUpdateType)) await asyncio.sleep(0.1) assert self._feature_flag_added[0].name == 'bilal_split' assert telemetry_storage._counters._update_from_sse['sp'] == 2 # compression 1 self._feature_flag_added = None - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 2345, 'H4sIAAkVZWQC/8WST0+DQBDFv0qzZ0ig/BF6a2xjGismUk2MaZopzOKmy9Isy0EbvrtDwbY2Xo233Tdv5se85cCMBs5FtvrYYwIlsglratTMYiKns+chcAgc24UwsF0Xczt2cm5z8Jw8DmPH9wPyqr5zKyTITb2XwpA4TJ5KWWVgRKXYxHWcX/QUkVi264W+68bjaGyxupdCJ4i9KPI9UgyYpibI9Ha1eJnT/J2QsnNxkDVaLEcOjTQrjWBKVIasFefky95BFZg05Zb2mrhh5I9vgsiL44BAIIuKTeiQVYqLotHHLyLOoT1quRjub4fztQuLxj89LpePzytClGCyd9R3umr21ErOcitUh2PTZHY29HN2+JGixMxUujNfvMB3+u2pY1AXySad3z3Mk46msACDp8W7jhly4uUpFt3qD33vDAx0gLpXkx+P1GusbdcE24M2F4uaywwVEWvxSa1Oa13Vjvn2RXradm0xCVuUVBJqNCBGV0DrX4OcLpeb+/lreh3jH8Uw/JQj3UhkxPgCCurdEnADAAA=', 1)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 2345, 'd': 'H4sIAAkVZWQC/8WST0+DQBDFv0qzZ0ig/BF6a2xjGismUk2MaZopzOKmy9Isy0EbvrtDwbY2Xo233Tdv5se85cCMBs5FtvrYYwIlsglratTMYiKns+chcAgc24UwsF0Xczt2cm5z8Jw8DmPH9wPyqr5zKyTITb2XwpA4TJ5KWWVgRKXYxHWcX/QUkVi264W+68bjaGyxupdCJ4i9KPI9UgyYpibI9Ha1eJnT/J2QsnNxkDVaLEcOjTQrjWBKVIasFefky95BFZg05Zb2mrhh5I9vgsiL44BAIIuKTeiQVYqLotHHLyLOoT1quRjub4fztQuLxj89LpePzytClGCyd9R3umr21ErOcitUh2PTZHY29HN2+JGixMxUujNfvMB3+u2pY1AXySad3z3Mk46msACDp8W7jhly4uUpFt3qD33vDAx0gLpXkx+P1GusbdcE24M2F4uaywwVEWvxSa1Oa13Vjvn2RXradm0xCVuUVBJqNCBGV0DrX4OcLpeb+/lreh3jH8Uw/JQj3UhkxPgCCurdEnADAAA=', 'c': 1}, EventUpdateType)) await asyncio.sleep(0.1) assert self._feature_flag_added[0].name == 'bilal_split' assert telemetry_storage._counters._update_from_sse['sp'] == 3 @@ -462,7 +461,7 @@ async def contains(rbs): # should call delete split self._feature_flag_added = None self._feature_flag_deleted = None - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, 2345, 'eyJ0cmFmZmljVHlwZU5hbWUiOiAidXNlciIsICJpZCI6ICIzM2VhZmE1MC0xYTY1LTExZWQtOTBkZi1mYTMwZDk2OTA0NDUiLCAibmFtZSI6ICJiaWxhbF9zcGxpdCIsICJ0cmFmZmljQWxsb2NhdGlvbiI6IDEwMCwgInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6IC0xMzY0MTE5MjgyLCAic2VlZCI6IC02MDU5Mzg4NDMsICJzdGF0dXMiOiAiQVJDSElWRUQiLCAia2lsbGVkIjogZmFsc2UsICJkZWZhdWx0VHJlYXRtZW50IjogIm9mZiIsICJjaGFuZ2VOdW1iZXIiOiAxNjg0Mjc1ODM5OTUyLCAiYWxnbyI6IDIsICJjb25maWd1cmF0aW9ucyI6IHt9LCAiY29uZGl0aW9ucyI6IFt7ImNvbmRpdGlvblR5cGUiOiAiUk9MTE9VVCIsICJtYXRjaGVyR3JvdXAiOiB7ImNvbWJpbmVyIjogIkFORCIsICJtYXRjaGVycyI6IFt7ImtleVNlbGVjdG9yIjogeyJ0cmFmZmljVHlwZSI6ICJ1c2VyIn0sICJtYXRjaGVyVHlwZSI6ICJJTl9TRUdNRU5UIiwgIm5lZ2F0ZSI6IGZhbHNlLCAidXNlckRlZmluZWRTZWdtZW50TWF0Y2hlckRhdGEiOiB7InNlZ21lbnROYW1lIjogImJpbGFsX3NlZ21lbnQifX1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDB9LCB7InRyZWF0bWVudCI6ICJvZmYiLCAic2l6ZSI6IDEwMH1dLCAibGFiZWwiOiAiaW4gc2VnbWVudCBiaWxhbF9zZWdtZW50In0sIHsiY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIifSwgIm1hdGNoZXJUeXBlIjogIkFMTF9LRVlTIiwgIm5lZ2F0ZSI6IGZhbHNlfV19LCAicGFydGl0aW9ucyI6IFt7InRyZWF0bWVudCI6ICJvbiIsICJzaXplIjogMH0sIHsidHJlYXRtZW50IjogIm9mZiIsICJzaXplIjogMTAwfV0sICJsYWJlbCI6ICJkZWZhdWx0IHJ1bGUifV19', 0)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456790, {'pcn': 2345, 'd': 'eyJ0cmFmZmljVHlwZU5hbWUiOiAidXNlciIsICJpZCI6ICIzM2VhZmE1MC0xYTY1LTExZWQtOTBkZi1mYTMwZDk2OTA0NDUiLCAibmFtZSI6ICJiaWxhbF9zcGxpdCIsICJ0cmFmZmljQWxsb2NhdGlvbiI6IDEwMCwgInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6IC0xMzY0MTE5MjgyLCAic2VlZCI6IC02MDU5Mzg4NDMsICJzdGF0dXMiOiAiQVJDSElWRUQiLCAia2lsbGVkIjogZmFsc2UsICJkZWZhdWx0VHJlYXRtZW50IjogIm9mZiIsICJjaGFuZ2VOdW1iZXIiOiAxNjg0Mjc1ODM5OTUyLCAiYWxnbyI6IDIsICJjb25maWd1cmF0aW9ucyI6IHt9LCAiY29uZGl0aW9ucyI6IFt7ImNvbmRpdGlvblR5cGUiOiAiUk9MTE9VVCIsICJtYXRjaGVyR3JvdXAiOiB7ImNvbWJpbmVyIjogIkFORCIsICJtYXRjaGVycyI6IFt7ImtleVNlbGVjdG9yIjogeyJ0cmFmZmljVHlwZSI6ICJ1c2VyIn0sICJtYXRjaGVyVHlwZSI6ICJJTl9TRUdNRU5UIiwgIm5lZ2F0ZSI6IGZhbHNlLCAidXNlckRlZmluZWRTZWdtZW50TWF0Y2hlckRhdGEiOiB7InNlZ21lbnROYW1lIjogImJpbGFsX3NlZ21lbnQifX1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDB9LCB7InRyZWF0bWVudCI6ICJvZmYiLCAic2l6ZSI6IDEwMH1dLCAibGFiZWwiOiAiaW4gc2VnbWVudCBiaWxhbF9zZWdtZW50In0sIHsiY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIifSwgIm1hdGNoZXJUeXBlIjogIkFMTF9LRVlTIiwgIm5lZ2F0ZSI6IGZhbHNlfV19LCAicGFydGl0aW9ucyI6IFt7InRyZWF0bWVudCI6ICJvbiIsICJzaXplIjogMH0sIHsidHJlYXRtZW50IjogIm9mZiIsICJzaXplIjogMTAwfV0sICJsYWJlbCI6ICJkZWZhdWx0IHJ1bGUifV19', 'c': 0}, EventUpdateType)) await asyncio.sleep(0.1) assert self._feature_flag_deleted[0] == 'bilal_split' assert self._feature_flag_added == [] @@ -472,7 +471,7 @@ async def contains(rbs): @pytest.mark.asyncio async def test_edge_cases(self, mocker): q = asyncio.Queue() - split_worker = SplitWorkerAsync(handler_async, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) + split_worker = SplitWorkerAsync(handler_async, mocker.Mock(), q, mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock(), mocker.Mock()) global change_number_received split_worker.start() @@ -492,7 +491,7 @@ async def update(feature_flag_add, feature_flag_delete, change_number): # should Not call the handler self._feature_flag_added = None change_number_received = 0 - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, 2345, "/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 2)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': 2345, 'd': "/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 'c': 2}, EventUpdateType)) await asyncio.sleep(0.1) assert self._feature_flag_added == None @@ -500,21 +499,21 @@ async def update(feature_flag_add, feature_flag_delete, change_number): # should Not call the handler self._feature_flag_added = None change_number_received = 0 - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, 2345, "/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 4)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': 2345, 'd': "/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==", 'c': 4}, EventUpdateType)) await asyncio.sleep(0.1) assert self._feature_flag_added == None # should Not call the handler self._feature_flag_added = None change_number_received = 0 - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, None, 'eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==', 2)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': None, 'd': 'eJzEUtFq20AQ/JUwz2c4WZZr3ZupTQh1FKjcQinGrKU95cjpZE6nh9To34ssJ3FNX0sfd3Zm53b2TgietDbF9vXIGdUMha5lDwFTQiGOmTQlchLRPJlEEZeTVJZ6oimWZTpP5WyWQMCNyoOxZPft0ZoA8TZ5aW1TUDCNg4qk/AueM5dQkyiez6IonS6mAu0IzWWSxovFLBZoA4WuhcLy8/bh+xoCL8bagaXJtixQsqbOhq1nCjW7AIVGawgUz+Qqzrr6wB4qmi9m00/JIk7TZCpAtmqgpgJF47SpOn9+UQt16s9YaS71z9NHOYQFha9Pm83Tty0EagrFM/t733RHqIFZH4wb7LDMVh+Ecc4Lv+ZsuQiNH8hXF3hLv39XXNCHbJ+v7x/X2eDmuKLA74sPihVr47jMuRpWfxy1Kwo0GLQjmv1xpBFD3+96gSP5cLVouM7QQaA1vxhK9uKmd853bEZS9jsBSwe2UDDu7mJxd2Mo/muQy81m/2X9I7+N8R/FcPmUd76zjH7X/w4AAP//90glTw==', 'c': 2}, EventUpdateType)) await asyncio.sleep(0.1) assert self._feature_flag_added == None # should Not call the handler self._feature_flag_added = None change_number_received = 0 - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, 2345, None, 1)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 123456, {'pcn': 2345, 'd': None, 'c': 1}, EventUpdateType)) await asyncio.sleep(0.1) assert self._feature_flag_added == None @@ -523,15 +522,14 @@ async def update(feature_flag_add, feature_flag_delete, change_number): @pytest.mark.asyncio async def test_fetch_segment(self, mocker): q = asyncio.Queue() - internal_events_queue = asyncio.Queue() - split_storage = InMemoryDefinitionStorageAsync(internal_events_queue) - segment_storage = InMemorySegmentStorageAsync(internal_events_queue) + split_storage = InMemoryDefinitionStorageAsync() + segment_storage = InMemorySegmentStorageAsync() self.segment_name = None async def segment_handler_sync(segment_name, change_number): self.segment_name = segment_name return - split_worker = SplitWorkerAsync(handler_async, segment_handler_sync, q, mocker.Mock(), split_storage, segment_storage, mocker.Mock(), mocker.Mock()) + split_worker = SplitWorkerAsync(handler_async, segment_handler_sync, q, mocker.Mock(), split_storage, segment_storage, mocker.Mock(), mocker.Mock(), mocker.Mock()) split_worker.start() async def get_change_number(): @@ -542,7 +540,7 @@ async def check_instant_ff_update(event): return True split_worker._check_instant_ff_update = check_instant_ff_update - await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 1675095324253, 2345, 'eyJjaGFuZ2VOdW1iZXIiOiAxNjc1MDk1MzI0MjUzLCAidHJhZmZpY1R5cGVOYW1lIjogInVzZXIiLCAibmFtZSI6ICJiaWxhbF9zcGxpdCIsICJ0cmFmZmljQWxsb2NhdGlvbiI6IDEwMCwgInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6IC0xMzY0MTE5MjgyLCAic2VlZCI6IC02MDU5Mzg4NDMsICJzdGF0dXMiOiAiQUNUSVZFIiwgImtpbGxlZCI6IGZhbHNlLCAiZGVmYXVsdFRyZWF0bWVudCI6ICJvZmYiLCAiYWxnbyI6IDIsICJjb25kaXRpb25zIjogW3siY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIiLCAiYXR0cmlidXRlIjogbnVsbH0sICJtYXRjaGVyVHlwZSI6ICJJTl9TRUdNRU5UIiwgIm5lZ2F0ZSI6IGZhbHNlLCAidXNlckRlZmluZWRTZWdtZW50TWF0Y2hlckRhdGEiOiB7InNlZ21lbnROYW1lIjogImJpbGFsX3NlZ21lbnQifSwgIndoaXRlbGlzdE1hdGNoZXJEYXRhIjogbnVsbCwgInVuYXJ5TnVtZXJpY01hdGNoZXJEYXRhIjogbnVsbCwgImJldHdlZW5NYXRjaGVyRGF0YSI6IG51bGwsICJkZXBlbmRlbmN5TWF0Y2hlckRhdGEiOiBudWxsLCAiYm9vbGVhbk1hdGNoZXJEYXRhIjogbnVsbCwgInN0cmluZ01hdGNoZXJEYXRhIjogbnVsbH1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDB9LCB7InRyZWF0bWVudCI6ICJvZmYiLCAic2l6ZSI6IDEwMH1dLCAibGFiZWwiOiAiaW4gc2VnbWVudCBiaWxhbF9zZWdtZW50In0sIHsiY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIiLCAiYXR0cmlidXRlIjogbnVsbH0sICJtYXRjaGVyVHlwZSI6ICJBTExfS0VZUyIsICJuZWdhdGUiOiBmYWxzZSwgInVzZXJEZWZpbmVkU2VnbWVudE1hdGNoZXJEYXRhIjogbnVsbCwgIndoaXRlbGlzdE1hdGNoZXJEYXRhIjogbnVsbCwgInVuYXJ5TnVtZXJpY01hdGNoZXJEYXRhIjogbnVsbCwgImJldHdlZW5NYXRjaGVyRGF0YSI6IG51bGwsICJkZXBlbmRlbmN5TWF0Y2hlckRhdGEiOiBudWxsLCAiYm9vbGVhbk1hdGNoZXJEYXRhIjogbnVsbCwgInN0cmluZ01hdGNoZXJEYXRhIjogbnVsbH1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDUwfSwgeyJ0cmVhdG1lbnQiOiAib2ZmIiwgInNpemUiOiA1MH1dLCAibGFiZWwiOiAiZGVmYXVsdCBydWxlIn1dLCAiY29uZmlndXJhdGlvbnMiOiB7fX0=', 0)) + await q.put(SplitChangeUpdate('some', 'SPLIT_UPDATE', 1675095324253, {'pcn': 2345, 'd': 'eyJjaGFuZ2VOdW1iZXIiOiAxNjc1MDk1MzI0MjUzLCAidHJhZmZpY1R5cGVOYW1lIjogInVzZXIiLCAibmFtZSI6ICJiaWxhbF9zcGxpdCIsICJ0cmFmZmljQWxsb2NhdGlvbiI6IDEwMCwgInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6IC0xMzY0MTE5MjgyLCAic2VlZCI6IC02MDU5Mzg4NDMsICJzdGF0dXMiOiAiQUNUSVZFIiwgImtpbGxlZCI6IGZhbHNlLCAiZGVmYXVsdFRyZWF0bWVudCI6ICJvZmYiLCAiYWxnbyI6IDIsICJjb25kaXRpb25zIjogW3siY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIiLCAiYXR0cmlidXRlIjogbnVsbH0sICJtYXRjaGVyVHlwZSI6ICJJTl9TRUdNRU5UIiwgIm5lZ2F0ZSI6IGZhbHNlLCAidXNlckRlZmluZWRTZWdtZW50TWF0Y2hlckRhdGEiOiB7InNlZ21lbnROYW1lIjogImJpbGFsX3NlZ21lbnQifSwgIndoaXRlbGlzdE1hdGNoZXJEYXRhIjogbnVsbCwgInVuYXJ5TnVtZXJpY01hdGNoZXJEYXRhIjogbnVsbCwgImJldHdlZW5NYXRjaGVyRGF0YSI6IG51bGwsICJkZXBlbmRlbmN5TWF0Y2hlckRhdGEiOiBudWxsLCAiYm9vbGVhbk1hdGNoZXJEYXRhIjogbnVsbCwgInN0cmluZ01hdGNoZXJEYXRhIjogbnVsbH1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDB9LCB7InRyZWF0bWVudCI6ICJvZmYiLCAic2l6ZSI6IDEwMH1dLCAibGFiZWwiOiAiaW4gc2VnbWVudCBiaWxhbF9zZWdtZW50In0sIHsiY29uZGl0aW9uVHlwZSI6ICJST0xMT1VUIiwgIm1hdGNoZXJHcm91cCI6IHsiY29tYmluZXIiOiAiQU5EIiwgIm1hdGNoZXJzIjogW3sia2V5U2VsZWN0b3IiOiB7InRyYWZmaWNUeXBlIjogInVzZXIiLCAiYXR0cmlidXRlIjogbnVsbH0sICJtYXRjaGVyVHlwZSI6ICJBTExfS0VZUyIsICJuZWdhdGUiOiBmYWxzZSwgInVzZXJEZWZpbmVkU2VnbWVudE1hdGNoZXJEYXRhIjogbnVsbCwgIndoaXRlbGlzdE1hdGNoZXJEYXRhIjogbnVsbCwgInVuYXJ5TnVtZXJpY01hdGNoZXJEYXRhIjogbnVsbCwgImJldHdlZW5NYXRjaGVyRGF0YSI6IG51bGwsICJkZXBlbmRlbmN5TWF0Y2hlckRhdGEiOiBudWxsLCAiYm9vbGVhbk1hdGNoZXJEYXRhIjogbnVsbCwgInN0cmluZ01hdGNoZXJEYXRhIjogbnVsbH1dfSwgInBhcnRpdGlvbnMiOiBbeyJ0cmVhdG1lbnQiOiAib24iLCAic2l6ZSI6IDUwfSwgeyJ0cmVhdG1lbnQiOiAib2ZmIiwgInNpemUiOiA1MH1dLCAibGFiZWwiOiAiZGVmYXVsdCBydWxlIn1dLCAiY29uZmlndXJhdGlvbnMiOiB7fX0=', 'c': 0}, EventUpdateType)) await asyncio.sleep(0.1) assert self.segment_name == "bilal_segment" diff --git a/tests/sync/test_splits_synchronizer.py b/tests/sync/test_splits_synchronizer.py index a8755e68..07c8d860 100644 --- a/tests/sync/test_splits_synchronizer.py +++ b/tests/sync/test_splits_synchronizer.py @@ -399,9 +399,9 @@ def intersect(sets): def test_sync_flag_sets_with_config_sets(self, mocker): """Test split sync with flag sets.""" events_queue = queue.Queue() - storage = InMemorySplitStorage(events_queue, ['set1', 'set2']) + storage = InMemorySplitStorage(['set1', 'set2']) events_queue = queue.Queue() - rbs_storage = InMemoryRuleBasedSegmentStorage(events_queue) + rbs_storage = InMemoryRuleBasedSegmentStorage() split = copy.deepcopy(self.splits[0]) split['name'] = 'second' @@ -447,8 +447,8 @@ def get_changes(*args, **kwargs): def test_sync_flag_sets_without_config_sets(self, mocker): """Test split sync with flag sets.""" events_queue = queue.Queue() - storage = InMemorySplitStorage(events_queue) - rbs_storage = InMemoryRuleBasedSegmentStorage(events_queue) + storage = InMemorySplitStorage() + rbs_storage = InMemoryRuleBasedSegmentStorage() split = copy.deepcopy(self.splits[0]) split['name'] = 'second' splits1 = [self.splits[0].copy(), split] @@ -787,8 +787,8 @@ async def clear(): async def test_sync_flag_sets_with_config_sets(self, mocker): """Test split sync with flag sets.""" internal_events_queue = asyncio.Queue() - storage = InMemorySplitStorageAsync(internal_events_queue, ['set1', 'set2']) - rbs_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + storage = InMemorySplitStorageAsync(['set1', 'set2']) + rbs_storage = InMemoryRuleBasedSegmentStorageAsync() split = self.splits[0].copy() split['name'] = 'second' @@ -836,8 +836,8 @@ async def get_changes(*args, **kwargs): async def test_sync_flag_sets_without_config_sets(self, mocker): """Test split sync with flag sets.""" internal_events_queue = asyncio.Queue() - storage = InMemorySplitStorageAsync(internal_events_queue) - rbs_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + storage = InMemorySplitStorageAsync() + rbs_storage = InMemoryRuleBasedSegmentStorageAsync() split = self.splits[0].copy() split['name'] = 'second' splits1 = [self.splits[0].copy(), split] @@ -896,8 +896,8 @@ def test_synchronize_definitions_error(self, mocker): def test_synchronize_definitions(self, mocker): """Test split sync.""" events_queue = queue.Queue() - storage = InMemorySplitStorage(events_queue) - rbs_storage = InMemoryRuleBasedSegmentStorage(events_queue) + storage = InMemorySplitStorage() + rbs_storage = InMemoryRuleBasedSegmentStorage() def read_splits_from_json_file(*args, **kwargs): return self.payload @@ -941,8 +941,8 @@ def read_splits_from_json_file(*args, **kwargs): def test_sync_flag_sets_with_config_sets(self, mocker): """Test split sync with flag sets.""" events_queue = queue.Queue() - storage = InMemorySplitStorage(events_queue, ['set1', 'set2']) - rbs_storage = InMemoryRuleBasedSegmentStorage(events_queue) + storage = InMemorySplitStorage(['set1', 'set2']) + rbs_storage = InMemoryRuleBasedSegmentStorage() split = self.payload["ff"]["d"][0].copy() split['name'] = 'second' @@ -984,8 +984,8 @@ def read_feature_flags_from_json_file(*args, **kwargs): def test_sync_flag_sets_without_config_sets(self, mocker): """Test split sync with flag sets.""" events_queue = queue.Queue() - storage = InMemorySplitStorage(events_queue) - rbs_storage = InMemoryRuleBasedSegmentStorage(events_queue) + storage = InMemorySplitStorage() + rbs_storage = InMemoryRuleBasedSegmentStorage() split = self.payload["ff"]["d"][0].copy() split['name'] = 'second' @@ -1030,8 +1030,8 @@ def test_reading_json(self, mocker): f.write(json.dumps(self.payload)) f.close() events_queue = queue.Queue() - storage = InMemorySplitStorage(events_queue) - rbs_storage = InMemoryRuleBasedSegmentStorage(events_queue) + storage = InMemorySplitStorage() + rbs_storage = InMemoryRuleBasedSegmentStorage() split_synchronizer = LocalSplitSynchronizer("./splits.json", storage, rbs_storage, LocalhostMode.JSON) split_synchronizer.synchronize_definitions() @@ -1258,8 +1258,8 @@ async def test_synchronize_definitions_error(self, mocker): async def test_synchronize_definitions(self, mocker): """Test split sync.""" internal_events_queue = asyncio.Queue() - storage = InMemorySplitStorageAsync(internal_events_queue) - rbs_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + storage = InMemorySplitStorageAsync() + rbs_storage = InMemoryRuleBasedSegmentStorageAsync() async def read_splits_from_json_file(*args, **kwargs): return self.payload @@ -1304,8 +1304,8 @@ async def read_splits_from_json_file(*args, **kwargs): async def test_sync_flag_sets_with_config_sets(self, mocker): """Test split sync with flag sets.""" internal_events_queue = asyncio.Queue() - storage = InMemorySplitStorageAsync(internal_events_queue, ['set1', 'set2']) - rbs_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + storage = InMemorySplitStorageAsync(['set1', 'set2']) + rbs_storage = InMemoryRuleBasedSegmentStorageAsync() split = self.payload["ff"]["d"][0].copy() split['name'] = 'second' @@ -1348,8 +1348,8 @@ async def read_feature_flags_from_json_file(*args, **kwargs): async def test_sync_flag_sets_without_config_sets(self, mocker): """Test split sync with flag sets.""" internal_events_queue = asyncio.Queue() - storage = InMemorySplitStorageAsync(internal_events_queue) - rbs_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + storage = InMemorySplitStorageAsync() + rbs_storage = InMemoryRuleBasedSegmentStorageAsync() split = self.payload["ff"]["d"][0].copy() split['name'] = 'second' @@ -1393,8 +1393,8 @@ async def test_reading_json(self, mocker): async with aiofiles.open("./splits.json", "w") as f: await f.write(json.dumps(self.payload)) internal_events_queue = asyncio.Queue() - storage = InMemorySplitStorageAsync(internal_events_queue) - rbs_storage = InMemoryRuleBasedSegmentStorageAsync(internal_events_queue) + storage = InMemorySplitStorageAsync() + rbs_storage = InMemoryRuleBasedSegmentStorageAsync() split_synchronizer = LocalSplitSynchronizerAsync("./splits.json", storage, rbs_storage, LocalhostMode.JSON) await split_synchronizer.synchronize_definitions()