diff --git a/src/Splitio/Constants/Constants.cs b/src/Splitio/Constants/Constants.cs index f728b179d..318606c6e 100644 --- a/src/Splitio/Constants/Constants.cs +++ b/src/Splitio/Constants/Constants.cs @@ -65,5 +65,7 @@ public static class ApiVersions public static class EventMetadataKeys { public static string Flags => "flags"; + public static string Segments => "segments"; + public static string RuleBasedSegments => "ruleBasedSegments"; } } diff --git a/src/Splitio/Services/Cache/Classes/InMemoryRuleBasedSegmentCache.cs b/src/Splitio/Services/Cache/Classes/InMemoryRuleBasedSegmentCache.cs index 554e20358..998e419a8 100644 --- a/src/Splitio/Services/Cache/Classes/InMemoryRuleBasedSegmentCache.cs +++ b/src/Splitio/Services/Cache/Classes/InMemoryRuleBasedSegmentCache.cs @@ -1,5 +1,7 @@ -using Splitio.Domain; +using Splitio.Constants; +using Splitio.Domain; using Splitio.Services.Cache.Interfaces; +using Splitio.Services.Common; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading.Tasks; @@ -10,12 +12,15 @@ public class InMemoryRuleBasedSegmentCache : IRuleBasedSegmentCache { private readonly ConcurrentDictionary _cache; private long _changeNumber; + private readonly IEventsManager _eventsManager; public InMemoryRuleBasedSegmentCache(ConcurrentDictionary cache, + IEventsManager eventsManger, long changeNumber = -1) { _cache = cache; _changeNumber = changeNumber; + _eventsManager = eventsManger; } #region Sync Methods @@ -45,17 +50,22 @@ public long GetChangeNumber() // Producer public void Update(List toAdd, List toRemove, long till) { + List toNotify = new List(); foreach (var rbSegment in toAdd) { _cache.AddOrUpdate(rbSegment.Name, rbSegment, (key, oldValue) => rbSegment); + toNotify.Add(rbSegment.Name); } foreach (var name in toRemove) { _cache.TryRemove(name, out var _); + toNotify.Add(name); } SetChangeNumber(till); + _eventsManager.NotifyInternalEvent(SdkInternalEvent.RuleBasedSegmentsUpdated, + new EventMetadata(new Dictionary { { EventMetadataKeys.RuleBasedSegments, toNotify } })); } public void SetChangeNumber(long changeNumber) diff --git a/src/Splitio/Services/Cache/Classes/InMemorySegmentCache.cs b/src/Splitio/Services/Cache/Classes/InMemorySegmentCache.cs index f94a3d51f..1a687722a 100644 --- a/src/Splitio/Services/Cache/Classes/InMemorySegmentCache.cs +++ b/src/Splitio/Services/Cache/Classes/InMemorySegmentCache.cs @@ -1,5 +1,7 @@ -using Splitio.Domain; +using Splitio.Constants; +using Splitio.Domain; using Splitio.Services.Cache.Interfaces; +using Splitio.Services.Common; using Splitio.Services.Logger; using Splitio.Services.Shared.Classes; using System.Collections.Concurrent; @@ -13,10 +15,12 @@ public class InMemorySegmentCache : ISegmentCache private readonly ISplitLogger _log = WrapperAdapter.Instance().GetLogger(typeof(InMemorySegmentCache)); private readonly ConcurrentDictionary _segments; + private readonly IEventsManager _eventsManager; - public InMemorySegmentCache(ConcurrentDictionary segments) + public InMemorySegmentCache(ConcurrentDictionary segments, IEventsManager eventsManger) { _segments = segments; + _eventsManager = eventsManger; } #region Methods Sync @@ -31,6 +35,8 @@ public void AddToSegment(string segmentName, List segmentKeys) } segment.AddKeys(segmentKeys); + _eventsManager.NotifyInternalEvent(SdkInternalEvent.SegmentsUpdated, + new EventMetadata(new Dictionary { { EventMetadataKeys.Segments, segmentName } })); } public void RemoveFromSegment(string segmentName, List segmentKeys) @@ -38,6 +44,8 @@ public void RemoveFromSegment(string segmentName, List segmentKeys) if (_segments.TryGetValue(segmentName, out Segment segment)) { segment.RemoveKeys(segmentKeys); + _eventsManager.NotifyInternalEvent(SdkInternalEvent.SegmentsUpdated, + new EventMetadata(new Dictionary { { EventMetadataKeys.Segments, segmentName } })); } } diff --git a/src/Splitio/Services/Cache/Classes/InMemorySplitCache.cs b/src/Splitio/Services/Cache/Classes/InMemorySplitCache.cs index bd3f53c09..1a99fd8cc 100644 --- a/src/Splitio/Services/Cache/Classes/InMemorySplitCache.cs +++ b/src/Splitio/Services/Cache/Classes/InMemorySplitCache.cs @@ -20,12 +20,12 @@ public class InMemorySplitCache : IFeatureFlagCache private readonly ConcurrentDictionary _featureFlags; private readonly ConcurrentDictionary _trafficTypes; private readonly ConcurrentDictionary> _flagSets; - private readonly EventsManager _eventsManager; + private readonly IEventsManager _eventsManager; private long _changeNumber; public InMemorySplitCache(ConcurrentDictionary featureFlags, - IFlagSetsFilter flagSetsFilter, EventsManager eventsManger, + IFlagSetsFilter flagSetsFilter, IEventsManager eventsManger, long changeNumber = -1) { _featureFlags = featureFlags; @@ -74,14 +74,13 @@ public void Update(List toAdd, List toRemove, long till) { DecreaseTrafficTypeCount(removedSplit); RemoveFromFlagSets(removedSplit.name, removedSplit.Sets); + eventsFlags.Add(featureFlagName); } } SetChangeNumber(till); _eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagsUpdated, - new EventMetadata(new Dictionary { { EventMetadataKeys.Flags, eventsFlags } }), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.FlagsUpdated, - _eventsManager)); + new EventMetadata(new Dictionary { { EventMetadataKeys.Flags, eventsFlags } })); } public void SetChangeNumber(long changeNumber) @@ -154,9 +153,7 @@ public void Kill(long changeNumber, string splitName, string defaultTreatment) _featureFlags.AddOrUpdate(featureFlag.name, featureFlag, (key, oldValue) => featureFlag); _eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagKilledNotification, - new EventMetadata(new Dictionary { { EventMetadataKeys.Flags, new List { { featureFlag.name } } } }), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.FlagKilledNotification, - _eventsManager)); + new EventMetadata(new Dictionary { { EventMetadataKeys.Flags, new List { { featureFlag.name } } } })); } diff --git a/src/Splitio/Services/Client/Classes/JSONFileClient.cs b/src/Splitio/Services/Client/Classes/JSONFileClient.cs index 2ef9df660..ec5a40aa6 100644 --- a/src/Splitio/Services/Client/Classes/JSONFileClient.cs +++ b/src/Splitio/Services/Client/Classes/JSONFileClient.cs @@ -35,8 +35,9 @@ public JSONFileClient(string splitsFilePath, IRuleBasedSegmentCache ruleBasedSegmentCache = null ) : base("localhost", fallbackTreatmentCalculator) { - _segmentCache = segmentCacheInstance ?? new InMemorySegmentCache(new ConcurrentDictionary()); - var rbsCache = ruleBasedSegmentCache ?? new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary()); + var eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); + _segmentCache = segmentCacheInstance ?? new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager); + var rbsCache = ruleBasedSegmentCache ?? new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary(), eventsManager); var segmentFetcher = new JSONFileSegmentFetcher(segmentsFilePath, _segmentCache); var splitChangeFetcher = new JSONFileSplitChangeFetcher(splitsFilePath); @@ -54,8 +55,6 @@ public JSONFileClient(string splitsFilePath, } BuildFlagSetsFilter(new HashSet()); - var eventsManager = new EventsManager(new EventsManagerConfig()); - _featureFlagCache = featureFlagCacheInstance ?? new InMemorySplitCache(new ConcurrentDictionary(parsedSplits), _flagSetsFilter, eventsManager); _impressionsLog = impressionsLog; _eventsLog = eventsLog; diff --git a/src/Splitio/Services/Client/Classes/LocalhostClient.cs b/src/Splitio/Services/Client/Classes/LocalhostClient.cs index 1afea359d..e42fca1ec 100644 --- a/src/Splitio/Services/Client/Classes/LocalhostClient.cs +++ b/src/Splitio/Services/Client/Classes/LocalhostClient.cs @@ -47,7 +47,7 @@ public LocalhostClient(ConfigurationOptions configurationOptions, FallbackTreatm BuildFlagSetsFilter(new HashSet()); - var eventsManager = new EventsManager(new EventsManagerConfig()); + var eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); var splits = _localhostFileService.ParseSplitFile(_fullPath); _featureFlagCache = new InMemorySplitCache(splits, _flagSetsFilter, eventsManager); diff --git a/src/Splitio/Services/Client/Classes/SelfRefreshingClient.cs b/src/Splitio/Services/Client/Classes/SelfRefreshingClient.cs index 04594e4de..370e6a2b8 100644 --- a/src/Splitio/Services/Client/Classes/SelfRefreshingClient.cs +++ b/src/Splitio/Services/Client/Classes/SelfRefreshingClient.cs @@ -92,7 +92,7 @@ public SelfRefreshingClient(string apiKey, ConfigurationOptions config, #region Private Methods private void BuildEventsManager() { - _eventsManager = new EventsManager(new EventsManagerConfig()); + _eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); } private void BuildSplitCache() { @@ -101,12 +101,12 @@ private void BuildSplitCache() private void BuildSegmentCache() { - _segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(_config.ConcurrencyLevel, InitialCapacity)); + _segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(_config.ConcurrencyLevel, InitialCapacity), _eventsManager); } private void BuildRuleBasedSegmentCache() { - _ruleBasedSegmentCache = new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary(_config.ConcurrencyLevel, InitialCapacity)); + _ruleBasedSegmentCache = new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary(_config.ConcurrencyLevel, InitialCapacity), _eventsManager); } private void BuildTelemetryStorage() diff --git a/src/Splitio/Services/Client/Classes/SplitClient.cs b/src/Splitio/Services/Client/Classes/SplitClient.cs index 54297fdf8..c8d383f9d 100644 --- a/src/Splitio/Services/Client/Classes/SplitClient.cs +++ b/src/Splitio/Services/Client/Classes/SplitClient.cs @@ -64,6 +64,10 @@ public abstract class SplitClient : ISplitClient protected IClientExtensionService _clientExtensionService; protected IFlagSetsFilter _flagSetsFilter; + public event EventHandler SdkReady; + public event EventHandler SdkUpdate; + public event EventHandler SdkTimedOut; + protected SplitClient(string apikey, FallbackTreatmentCalculator fallbackTreatmentCalculator) { ApiKey = apikey; diff --git a/src/Splitio/Services/Client/Interfaces/ISplitClient.cs b/src/Splitio/Services/Client/Interfaces/ISplitClient.cs index 60e0b751b..a18982ddd 100644 --- a/src/Splitio/Services/Client/Interfaces/ISplitClient.cs +++ b/src/Splitio/Services/Client/Interfaces/ISplitClient.cs @@ -1,10 +1,15 @@ using Splitio.Domain; +using System; using System.Collections.Generic; namespace Splitio.Services.Client.Interfaces { public interface ISplitClient : ISplitClientAsync { + event EventHandler SdkReady; + event EventHandler SdkUpdate; + event EventHandler SdkTimedOut; + /// /// Returns the treatment to show this key for this feature flag. /// The set of treatments for a feature flag can be configured on the Split user interface. diff --git a/src/Splitio/Services/Common/EventDelivery.cs b/src/Splitio/Services/Common/EventDelivery.cs index be28dd36b..288cb018b 100644 --- a/src/Splitio/Services/Common/EventDelivery.cs +++ b/src/Splitio/Services/Common/EventDelivery.cs @@ -8,14 +8,14 @@ public class EventDelivery : IEventDelivery { private readonly ISplitLogger _logger = WrapperAdapter.Instance().GetLogger("EventDelivery"); - public virtual void Deliver(E sdkEvent, M eventMetadata, EventHandler handler) + public virtual void Deliver(E sdkEvent, M eventMetadata, Action handler) { if (handler != null) { _logger.Debug($"EventDelivery: Triggering handle for Sdk Event {sdkEvent}"); try { - handler(this, eventMetadata); + handler.Invoke(eventMetadata); } catch (Exception e) { diff --git a/src/Splitio/Services/Common/EventsManager.cs b/src/Splitio/Services/Common/EventsManager.cs index acb23688e..bda64bd6f 100644 --- a/src/Splitio/Services/Common/EventsManager.cs +++ b/src/Splitio/Services/Common/EventsManager.cs @@ -4,33 +4,40 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; namespace Splitio.Services.Common { public class EventsManager : IEventsManager { + public struct ValidSdkEvent + { + public E SdkEvent { get; set; } + public bool Valid { get; set; } + } + private struct PublicEventProperties { public bool Triggered; - public EventHandler EventHandler; + public Action EventHandler; } private readonly ConcurrentDictionary _activeSubscriptions; private readonly ConcurrentDictionary _internalEventsStatus; private readonly ISplitLogger _logger = WrapperAdapter.Instance().GetLogger("EventsManager"); - private readonly EventDelivery _eventDelivery; + private readonly IEventDelivery _eventDelivery; private readonly object _lock = new object(); - public EventsManagerConfig ManagerConfig { get; private set; } + public EventManagerConfigData _managerConfig { get; private set; } - public EventsManager(EventsManagerConfig eventsManagerConfig) + public EventsManager(EventManagerConfigData eventsManagerConfig, IEventDelivery eventDelivery) { _activeSubscriptions = new ConcurrentDictionary(); _internalEventsStatus = new ConcurrentDictionary(); - _eventDelivery = new EventDelivery(); - ManagerConfig = eventsManagerConfig; + _eventDelivery = eventDelivery; + _managerConfig = eventsManagerConfig; } #region Public Methods - public void Register(E sdkEvent, EventHandler handler) + public void Register(E sdkEvent, Action handler) { if (_activeSubscriptions.TryGetValue(sdkEvent, out var _)) { @@ -53,13 +60,13 @@ public void Unregister(E sdkEvent) } } - public void NotifyInternalEvent(I sdkInternalEvent, M eventMetadata, List eventsToNotify) + public void NotifyInternalEvent(I sdkInternalEvent, M eventMetadata) { lock (_lock) { _logger.Debug($"EventsManager: Handling internal event {sdkInternalEvent}"); - foreach (E sdkEvent in eventsToNotify) + foreach (E sdkEvent in GetSdkEventIfApplicable(sdkInternalEvent)) { _logger.Debug($"EventsManager: Firing Sdk event {sdkEvent}"); _eventDelivery.Deliver(sdkEvent, eventMetadata, GetEventHandler(sdkEvent)); @@ -109,7 +116,7 @@ private void SetSdkEventTriggered(E sdkEvent) _activeSubscriptions.TryUpdate(sdkEvent, newEventData, eventData); } - private EventHandler GetEventHandler(E sdkEvent) + private Action GetEventHandler(E sdkEvent) { if (!_activeSubscriptions.TryGetValue(sdkEvent, out var eventData)) { @@ -118,6 +125,114 @@ private EventHandler GetEventHandler(E sdkEvent) return eventData.EventHandler; } + + public List GetSdkEventIfApplicable(I sdkInternalEvent) + { + ValidSdkEvent finalSdkEvent = new ValidSdkEvent + { + Valid = false + }; + UpdateSdkInternalEventStatus(sdkInternalEvent, true); + List eventsToFire = new List(); + + ValidSdkEvent requireAnySdkEvent = CheckRequireAny(sdkInternalEvent); + if (requireAnySdkEvent.Valid) + { + if ((!EventAlreadyTriggered(requireAnySdkEvent.SdkEvent) + && ExecutionLimit(requireAnySdkEvent.SdkEvent) == 1) || ExecutionLimit(requireAnySdkEvent.SdkEvent) == -1) + { + finalSdkEvent.SdkEvent = requireAnySdkEvent.SdkEvent; + } + + finalSdkEvent.Valid = CheckPrerequisites(finalSdkEvent.SdkEvent) + && CheckSuppressedBy(finalSdkEvent.SdkEvent); + + if (finalSdkEvent.Valid) + { + eventsToFire.Add(finalSdkEvent.SdkEvent); + } + } + + foreach (E sdkEvent in CheckRequireAll()) + { + eventsToFire.Add(sdkEvent); + } + + return eventsToFire; + } + + private List CheckRequireAll() + { + List events = new List(); + foreach (KeyValuePair> kvp in _managerConfig.RequireAll) + { + bool finalStatus = true; + foreach (var val in kvp.Value) + { + finalStatus &= GetSdkInternalEventStatus(val); + } + if (finalStatus + && CheckPrerequisites(kvp.Key) + && ((ExecutionLimit(kvp.Key) == 1 && !EventAlreadyTriggered(kvp.Key)) + || (ExecutionLimit(kvp.Key) == -1)) + && kvp.Value.Count > 0) + { + events.Add(kvp.Key); + } + } + + return events; + } + + private bool CheckPrerequisites(E sdkEvent) + { + if (_managerConfig.Prerequisites.Any(kvp => kvp.Key.Equals(sdkEvent) && + kvp.Value.Any(x => !EventAlreadyTriggered(x)))) + { + return false; + } + + return true; + } + + private bool CheckSuppressedBy(E sdkEvent) + { + if (_managerConfig.SuppressedBy.Any(kvp => kvp.Key.Equals(sdkEvent) && + kvp.Value.Any(x => EventAlreadyTriggered(x)))) + { + return false; + } + + return true; + } + + private int ExecutionLimit(E sdkEvent) + { + if (!_managerConfig.ExecutionLimits.TryGetValue(sdkEvent, out int limit)) + { + return -1; + } + + return limit; + } + + private ValidSdkEvent CheckRequireAny(I sdkInternalEvent) + { + ValidSdkEvent validSdkEvent = new ValidSdkEvent + { + Valid = false + }; + + var sdkEvent = _managerConfig.RequireAny.Where(kvp => kvp.Value.Contains(sdkInternalEvent)); + if (sdkEvent.Any()) + { + validSdkEvent.Valid = true; + validSdkEvent.SdkEvent = sdkEvent.First().Key; + return validSdkEvent; + } + + return validSdkEvent; + } #endregion } } diff --git a/src/Splitio/Services/Common/IEventDelivery.cs b/src/Splitio/Services/Common/IEventDelivery.cs index 550cfbbf2..83bb4540d 100644 --- a/src/Splitio/Services/Common/IEventDelivery.cs +++ b/src/Splitio/Services/Common/IEventDelivery.cs @@ -1,10 +1,9 @@ -using Splitio.Domain; -using System; +using System; namespace Splitio.Services.Common { public interface IEventDelivery { - void Deliver(E sdkEvent, M eventMetadata, EventHandler handler); + void Deliver(E sdkEvent, M eventMetadata, Action handler); } } diff --git a/src/Splitio/Services/Common/IEventsManager.cs b/src/Splitio/Services/Common/IEventsManager.cs index fd606b1a9..ac5f37396 100644 --- a/src/Splitio/Services/Common/IEventsManager.cs +++ b/src/Splitio/Services/Common/IEventsManager.cs @@ -1,13 +1,12 @@ -using Splitio.Domain; -using System; -using System.Collections.Generic; +using System; namespace Splitio.Services.Common { public interface IEventsManager { - void NotifyInternalEvent(I sdkInternalEvent, M eventMetadata, List eventsToNotify); - void Register(E sdkEvent, EventHandler handler); + void NotifyInternalEvent(I sdkInternalEvent, M eventMetadata); + void Register(E sdkEvent, Action handler); void Unregister(E sdkEvent); + bool EventAlreadyTriggered(E sdkEvent); } } diff --git a/src/Splitio/Util/Helper.cs b/src/Splitio/Util/Helper.cs index c9854f239..84dc8dda1 100644 --- a/src/Splitio/Util/Helper.cs +++ b/src/Splitio/Util/Helper.cs @@ -1,6 +1,5 @@ using Splitio.CommonLibraries; using Splitio.Domain; -using Splitio.Services.Common; using Splitio.Services.Impressions.Classes; using Splitio.Services.Logger; using Splitio.Telemetry.Domain.Enums; @@ -12,12 +11,6 @@ namespace Splitio.Util { public class Helper { - public struct ValidSdkEvent - { - public SdkEvent SdkEvent { get; set; } - public bool Valid { get; set; } - } - public static List TakeFromList(List items, int size) { if (items == null) return new List(); @@ -91,144 +84,5 @@ public static string getFallbackConfig(FallbackTreatment fallbackTreatment) return null; } - - public static List GetSdkEventIfApplicable(SdkInternalEvent sdkInternalEvent, - EventsManager eventsManager) - { - ValidSdkEvent finalSdkEvent = new ValidSdkEvent - { - Valid = false, - SdkEvent = SdkEvent.SdkReady - }; - eventsManager.UpdateSdkInternalEventStatus(sdkInternalEvent, true); - List eventsToFire = new List(); - - ValidSdkEvent requireAnySdkEvent = CheckRequireAny(sdkInternalEvent, eventsManager.ManagerConfig); - if (requireAnySdkEvent.Valid) - { - if ((!eventsManager.EventAlreadyTriggered(requireAnySdkEvent.SdkEvent) - && ExecutionLimit(requireAnySdkEvent.SdkEvent, eventsManager.ManagerConfig) == 1) || ExecutionLimit(requireAnySdkEvent.SdkEvent, eventsManager.ManagerConfig) == -1) - { - finalSdkEvent.SdkEvent = requireAnySdkEvent.SdkEvent; - } - - finalSdkEvent.Valid = CheckPrerequisites(finalSdkEvent.SdkEvent, eventsManager) - && CheckSuppressedBy(finalSdkEvent.SdkEvent, eventsManager); - } - - if (finalSdkEvent.Valid) - { - eventsToFire.Add(finalSdkEvent.SdkEvent); - } - - foreach (SdkEvent sdkEvent in CheckRequireAll(eventsManager)) - { - eventsToFire.Add(sdkEvent); - } - - return eventsToFire; - } - - private static List CheckRequireAll( - EventsManager eventsManager) - { - List events = new List(); - foreach (KeyValuePair> kvp in eventsManager.ManagerConfig.RequireAll) - { - bool finalStatus = true; - foreach (var val in kvp.Value) - { - finalStatus &= eventsManager.GetSdkInternalEventStatus(val); - } - if (finalStatus - && CheckPrerequisites(kvp.Key, eventsManager) - && ((ExecutionLimit(kvp.Key, eventsManager.ManagerConfig) == 1 && !eventsManager.EventAlreadyTriggered(kvp.Key)) - || (ExecutionLimit(kvp.Key, eventsManager.ManagerConfig) == -1)) - && kvp.Value.Count > 0) - { - events.Add(kvp.Key); - } - } - - return events; - } - - private static bool CheckPrerequisites(SdkEvent sdkEvent, - EventsManager eventsManager) - { - foreach (KeyValuePair> kvp in eventsManager.ManagerConfig.Prerequisites) - { - if (kvp.Key == sdkEvent) - { - if (kvp.Value.Any(x => !eventsManager.EventAlreadyTriggered(x))) - { - return false; - } - - return true; - } - } - - return true; - } - - private static bool CheckSuppressedBy(SdkEvent sdkEvent, - EventsManager eventsManager) - { - foreach (KeyValuePair> kvp in eventsManager.ManagerConfig.SuppressedBy) - { - if (kvp.Key == sdkEvent) - { - if (kvp.Value.Any(x => eventsManager.EventAlreadyTriggered(x))) - { - return false; - } - - return true; - } - } - - return true; - } - - private static int ExecutionLimit(SdkEvent sdkEvent, EventsManagerConfig eventsManagerConfig) - { - if (!eventsManagerConfig.ExecutionLimits.ContainsKey(sdkEvent)) - return -1; - - eventsManagerConfig.ExecutionLimits.TryGetValue(sdkEvent, out int limit); - return limit; - } - - private static ValidSdkEvent CheckRequireAny(SdkInternalEvent sdkInternalEvent, EventsManagerConfig eventsManagerConfig) - { - ValidSdkEvent validSdkEvent = new ValidSdkEvent - { - Valid = false, - SdkEvent = SdkEvent.SdkUpdate - }; - - foreach (KeyValuePair> kvp in eventsManagerConfig.RequireAny) - { - if (kvp.Value.Contains(sdkInternalEvent)) - { - validSdkEvent.Valid = true; - validSdkEvent.SdkEvent = kvp.Key; - return validSdkEvent; - } - } - - return validSdkEvent; - } - - public static void BuildInternalSdkEventStatus(EventsManager eventsManager) - { - eventsManager.UpdateSdkInternalEventStatus(SdkInternalEvent.SdkReady, false); - eventsManager.UpdateSdkInternalEventStatus(SdkInternalEvent.RuleBasedSegmentsUpdated, false); - eventsManager.UpdateSdkInternalEventStatus(SdkInternalEvent.SdkTimedOut, false); - eventsManager.UpdateSdkInternalEventStatus(SdkInternalEvent.SegmentsUpdated, false); - eventsManager.UpdateSdkInternalEventStatus(SdkInternalEvent.FlagKilledNotification, false); - eventsManager.UpdateSdkInternalEventStatus(SdkInternalEvent.FlagsUpdated, false); - } } } diff --git a/tests/Splitio-tests/Integration Tests/SelfRefreshingSegmentFetcherTests.cs b/tests/Splitio-tests/Integration Tests/SelfRefreshingSegmentFetcherTests.cs index 10cf92515..708396008 100644 --- a/tests/Splitio-tests/Integration Tests/SelfRefreshingSegmentFetcherTests.cs +++ b/tests/Splitio-tests/Integration Tests/SelfRefreshingSegmentFetcherTests.cs @@ -1,6 +1,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Splitio.Domain; using Splitio.Services.Cache.Classes; +using Splitio.Services.Common; using Splitio.Services.SegmentFetcher.Classes; using System.Collections.Concurrent; @@ -26,7 +27,8 @@ public SelfRefreshingSegmentFetcherTests() public void ExecuteGetSuccessfulWithResultsFromJSONFile() { //Arrange - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + var eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager); var segmentFetcher = new JSONFileSegmentFetcher($"{rootFilePath}segment_payed.json", segmentCache); diff --git a/tests/Splitio-tests/Integration Tests/TargetingRulesFetcherTests.cs b/tests/Splitio-tests/Integration Tests/TargetingRulesFetcherTests.cs index 52c5cb4f1..c949489c5 100644 --- a/tests/Splitio-tests/Integration Tests/TargetingRulesFetcherTests.cs +++ b/tests/Splitio-tests/Integration Tests/TargetingRulesFetcherTests.cs @@ -38,13 +38,13 @@ public TargetingRulesFetcherTests() public async Task ExecuteGetSuccessfulWithResultsFromJSONFile() { //Arrange - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); - var rbsCache = new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary()); + var eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager); + var rbsCache = new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary(), eventsManager); var segmentFetcher = new JSONFileSegmentFetcher($"{rootFilePath}segment_payed.json", segmentCache); var splitParser = new FeatureFlagParser(segmentCache, segmentFetcher); var splitChangeFetcher = new JSONFileSplitChangeFetcher($"{rootFilePath}splits_staging.json"); var flagSetsFilter = new FlagSetsFilter(new HashSet()); - var eventsManager = new EventsManager(new EventsManagerConfig()); var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), flagSetsFilter, eventsManager); var gates = new InMemoryReadinessGatesCache(); var taskManager = new TasksManager(gates); @@ -84,13 +84,13 @@ public async Task ExecuteGetSuccessfulWithResultsFromJSONFile() public async Task ExecuteGetSuccessfulWithResultsFromJSONFileIncludingTrafficAllocation() { //Arrange - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); - var rbsCache = new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary()); + var eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager); + var rbsCache = new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary(), eventsManager); var segmentFetcher = new JSONFileSegmentFetcher($"{rootFilePath}segment_payed.json", segmentCache); var splitParser = new FeatureFlagParser(segmentCache, segmentFetcher); var splitChangeFetcher = new JSONFileSplitChangeFetcher($"{rootFilePath}splits_staging_4.json"); var flagSetsFilter = new FlagSetsFilter(new HashSet()); - var eventsManager = new EventsManager(new EventsManagerConfig()); var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), flagSetsFilter, eventsManager); var gates = new InMemoryReadinessGatesCache(); var taskManager = new TasksManager(gates); @@ -142,16 +142,16 @@ public async Task ExecuteGetWithoutResults() var sdkSegmentApiClient = new SegmentSdkApiClient(httpClient, telemetryStorage, baseUrl); var apiSegmentChangeFetcher = new ApiSegmentChangeFetcher(sdkSegmentApiClient); var gates = new InMemoryReadinessGatesCache(); - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + var eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager); var segmentsQueue = new SplitQueue(); var taskManager = new TasksManager(gates); var worker = new SegmentTaskWorker(4, segmentsQueue); segmentsQueue.AddObserver(worker); var segmentsTask = taskManager.NewPeriodicTask(Splitio.Enums.Task.SegmentsFetcher, 3000); var segmentFetcher = new SelfRefreshingSegmentFetcher(apiSegmentChangeFetcher, segmentCache, segmentsQueue, segmentsTask, gates); - var rbsCache = new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary()); + var rbsCache = new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary(), eventsManager); var splitParser = new FeatureFlagParser(segmentCache, segmentFetcher); - var eventsManager = new EventsManager(new EventsManagerConfig()); var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), flagSetsFilter, eventsManager); var task = taskManager.NewPeriodicTask(Splitio.Enums.Task.FeatureFlagsFetcher, 3000); var featureFlagSyncService = new FeatureFlagUpdater(splitParser, splitCache, flagSetsFilter, rbsCache); diff --git a/tests/Splitio-tests/Unit Tests/Cache/InMemory/RuleBasedSegmentCacheTests.cs b/tests/Splitio-tests/Unit Tests/Cache/InMemory/RuleBasedSegmentCacheTests.cs index 763ac6ebe..023b5ce87 100644 --- a/tests/Splitio-tests/Unit Tests/Cache/InMemory/RuleBasedSegmentCacheTests.cs +++ b/tests/Splitio-tests/Unit Tests/Cache/InMemory/RuleBasedSegmentCacheTests.cs @@ -1,6 +1,8 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Splitio.Domain; using Splitio.Services.Cache.Classes; +using Splitio.Services.Common; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading.Tasks; @@ -11,12 +13,18 @@ namespace Splitio_Tests.Unit_Tests.Cache.InMemory public class RuleBasedSegmentCacheTests { private InMemoryRuleBasedSegmentCache _segmentCache; + private EventsManager _eventsManager; + private bool SdkUpdateFlag = false; + private EventMetadata eMetadata = null; + public event EventHandler SdkUpdate; + public event EventHandler SdkReady; [TestInitialize] public void Setup() { var cache = new ConcurrentDictionary(); - _segmentCache = new InMemoryRuleBasedSegmentCache(cache); + _eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); + _segmentCache = new InMemoryRuleBasedSegmentCache(cache, _eventsManager); } [TestMethod] @@ -142,5 +150,47 @@ public void Contains_ShouldReturnTrue() Assert.IsFalse(_segmentCache.Contains(new List { "segment1", "segment3" })); Assert.IsTrue(_segmentCache.Contains(new List { "segment1", "segment2" })); } + + [TestMethod] + public void Update_ShouldNotifyEvent() + { + // Arrange + var segmentToAdd = new RuleBasedSegment { Name = "segment-to-add" }; + var segmentToRemove = new RuleBasedSegment { Name = "segment-to-remove" }; + var till = 67890; + var toNotify = new List { { "segment-to-add" }, { "segment-to-remove" } }; + SdkUpdate += sdkUpdate_callback; + _eventsManager.Register(SdkEvent.SdkUpdate, TriggerSdkUpdate); + _eventsManager.Register(SdkEvent.SdkReady, TriggerSdkReady); + _eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(new Dictionary())); + + // Act + SdkUpdateFlag = false; + _segmentCache.Update(new List { segmentToAdd, segmentToRemove }, new List { segmentToRemove.Name }, till); + + // Assert + Assert.IsTrue(SdkUpdateFlag); + Assert.IsTrue(eMetadata.ContainKey(Splitio.Constants.EventMetadataKeys.RuleBasedSegments)); + List rbsegments = (List)eMetadata.GetData()[Splitio.Constants.EventMetadataKeys.RuleBasedSegments]; + Assert.IsTrue(rbsegments.Count == 3); + Assert.IsTrue(rbsegments.Contains("segment-to-add")); + Assert.IsTrue(rbsegments.Contains("segment-to-remove")); + } + + private void sdkUpdate_callback(object sender, EventMetadata metadata) + { + SdkUpdateFlag = true; + eMetadata = metadata; + } + + private void TriggerSdkReady(EventMetadata metaData) + { + SdkReady?.Invoke(this, metaData); + } + + private void TriggerSdkUpdate(EventMetadata metaData) + { + SdkUpdate?.Invoke(this, metaData); + } } } diff --git a/tests/Splitio-tests/Unit Tests/Cache/InMemory/SegmentCacheAsyncTests.cs b/tests/Splitio-tests/Unit Tests/Cache/InMemory/SegmentCacheAsyncTests.cs index c08a7515c..dcaf47d04 100644 --- a/tests/Splitio-tests/Unit Tests/Cache/InMemory/SegmentCacheAsyncTests.cs +++ b/tests/Splitio-tests/Unit Tests/Cache/InMemory/SegmentCacheAsyncTests.cs @@ -2,6 +2,8 @@ using Splitio.Domain; using Splitio.Services.Cache.Classes; using Splitio.Services.Cache.Interfaces; +using Splitio.Services.Common; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading.Tasks; @@ -12,12 +14,17 @@ namespace Splitio_Tests.Unit_Tests.Cache public class SegmentCacheAsyncTests { private readonly ISegmentCache _cache; + private EventsManager _eventsManager; + private bool SdkUpdateFlag = false; + private EventMetadata eMetadata = null; + public event EventHandler SdkUpdate; + public event EventHandler SdkReady; public SegmentCacheAsyncTests() { var segments = new ConcurrentDictionary(); - - _cache = new InMemorySegmentCache(segments); + _eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); + _cache = new InMemorySegmentCache(segments, _eventsManager); } [TestMethod] @@ -47,5 +54,43 @@ public async Task IsInSegmentAsyncTestTrue() //Assert Assert.IsTrue(result); } + + [TestMethod] + public async Task NotifyEventsTest() + { + //Arrange + var segmentName = "segment_test"; + var toNotify = new List { { segmentName } }; + SdkUpdate += sdkUpdate_callback; + _eventsManager.Register(SdkEvent.SdkUpdate, TriggerSdkUpdate); + _eventsManager.Register(SdkEvent.SdkReady, TriggerSdkReady); + _eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(new Dictionary())); + + //Act + SdkUpdateFlag = false; + _cache.AddToSegment(segmentName, new List { "abcd", "zzzzf" }); + + //Assert + Assert.IsTrue(SdkUpdateFlag); + Assert.IsTrue(eMetadata.ContainKey(Splitio.Constants.EventMetadataKeys.Segments)); + string segment = (string)eMetadata.GetData()[Splitio.Constants.EventMetadataKeys.Segments]; + Assert.AreEqual(segmentName, segment); + } + + private void sdkUpdate_callback(object sender, EventMetadata metadata) + { + SdkUpdateFlag = true; + eMetadata = metadata; + } + + private void TriggerSdkReady(EventMetadata metaData) + { + SdkReady?.Invoke(this, metaData); + } + + private void TriggerSdkUpdate(EventMetadata metaData) + { + SdkUpdate?.Invoke(this, metaData); + } } } diff --git a/tests/Splitio-tests/Unit Tests/Cache/InMemory/SegmentCacheTests.cs b/tests/Splitio-tests/Unit Tests/Cache/InMemory/SegmentCacheTests.cs index 287f18750..689d109b0 100644 --- a/tests/Splitio-tests/Unit Tests/Cache/InMemory/SegmentCacheTests.cs +++ b/tests/Splitio-tests/Unit Tests/Cache/InMemory/SegmentCacheTests.cs @@ -1,6 +1,9 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; using Splitio.Domain; using Splitio.Services.Cache.Classes; +using Splitio.Services.Common; +using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -9,11 +12,17 @@ namespace Splitio_Tests.Unit_Tests.Cache [TestClass] public class SegmentCacheTests { + private bool SdkUpdateFlag = false; + private EventMetadata eMetadata = null; + public event EventHandler SdkUpdate; + public event EventHandler SdkReady; + [TestMethod] public void RegisterSegmentTest() { //Arrange - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); var keys = new List { "abcd", "1234" }; var segmentName = "test"; @@ -29,7 +38,8 @@ public void RegisterSegmentTest() public void IsNotInSegmentTest() { //Arrange - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); var keys = new List { "1234" }; var segmentName = "test"; @@ -45,7 +55,8 @@ public void IsNotInSegmentTest() public void IsInSegmentWithInexistentSegmentTest() { //Arrange - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); //Act var result = segmentCache.IsInSegment("test", "abcd"); @@ -58,7 +69,8 @@ public void IsInSegmentWithInexistentSegmentTest() public void RemoveKeyFromSegmentTest() { //Arrange - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); var keys = new List { "1234" }; var segmentName = "test"; @@ -77,7 +89,8 @@ public void RemoveKeyFromSegmentTest() public void SetAndGetChangeNumberTest() { //Arrange - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); var segmentName = "test"; //Act @@ -88,5 +101,57 @@ public void SetAndGetChangeNumberTest() //Assert Assert.AreEqual(1234, result); } + + [TestMethod] + public void NotifyEventsTest() + { + //Arrange + var eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager); + var keys = new List { "1234" }; + var segmentName = "test"; + var toNotify = new List { { segmentName } }; + SdkUpdate += sdkUpdate_callback; + eventsManager.Register(SdkEvent.SdkUpdate, TriggerSdkUpdate); + eventsManager.Register(SdkEvent.SdkReady, TriggerSdkReady); + eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(new Dictionary())); + + // Act + SdkUpdateFlag = false; + segmentCache.AddToSegment(segmentName, keys); + + //Assert + Assert.IsTrue(SdkUpdateFlag); + Assert.IsTrue(eMetadata.ContainKey(Splitio.Constants.EventMetadataKeys.Segments)); + string segment = (string) eMetadata.GetData()[Splitio.Constants.EventMetadataKeys.Segments]; + Assert.AreEqual(segmentName, segment); + + // Act + SdkUpdateFlag = false; + eMetadata = null; + segmentCache.RemoveFromSegment(segmentName, keys); + + //Assert + Assert.IsTrue(SdkUpdateFlag); + Assert.IsTrue(eMetadata.ContainKey(Splitio.Constants.EventMetadataKeys.Segments)); + segment = (string)eMetadata.GetData()[Splitio.Constants.EventMetadataKeys.Segments]; + Assert.AreEqual(segmentName, segment); + } + + private void sdkUpdate_callback(object sender, EventMetadata metadata) + { + SdkUpdateFlag = true; + eMetadata = metadata; + } + + private void TriggerSdkReady(EventMetadata metaData) + { + SdkReady?.Invoke(this, metaData); + } + + private void TriggerSdkUpdate(EventMetadata metaData) + { + SdkUpdate?.Invoke(this, metaData); + } } } diff --git a/tests/Splitio-tests/Unit Tests/Cache/InMemory/SplitCacheAsyncTests.cs b/tests/Splitio-tests/Unit Tests/Cache/InMemory/SplitCacheAsyncTests.cs index 5d3b4c18f..985b62755 100644 --- a/tests/Splitio-tests/Unit Tests/Cache/InMemory/SplitCacheAsyncTests.cs +++ b/tests/Splitio-tests/Unit Tests/Cache/InMemory/SplitCacheAsyncTests.cs @@ -18,17 +18,16 @@ public class SplitCacheAsyncTests private readonly IFlagSetsFilter _flagSetsFilter; private readonly IFeatureFlagCache _cache; private readonly EventsManager _eventsManager; - private bool SdkUpdate = false; + private bool SdkUpdateFlag = false; private EventMetadata eMetadata = null; - public event EventHandler PublicSdkUpdateHandler; + public event EventHandler SdkUpdate; + public event EventHandler SdkReady; public SplitCacheAsyncTests() { _flagSetsFilter = new FlagSetsFilter(new HashSet()); var splits = new ConcurrentDictionary(); - _eventsManager = new EventsManager(new EventsManagerConfig()); - Splitio.Util.Helper.BuildInternalSdkEventStatus(_eventsManager); - + _eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); _cache = new InMemorySplitCache(splits, _flagSetsFilter, _eventsManager); } @@ -194,13 +193,12 @@ public async Task NotifyUpdateEventTest() }); toNotify.Add($"feature-flag-{i}"); } - PublicSdkUpdateHandler += sdkUpdate_callback; - _eventsManager.Register(SdkEvent.SdkUpdate, sdkUpdate_callback); - _eventsManager.Register(SdkEvent.SdkReady, sdkUpdate_callback); - _eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(new Dictionary()), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.SdkReady, _eventsManager)); + SdkUpdate += sdkUpdate_callback; + _eventsManager.Register(SdkEvent.SdkUpdate, TriggerSdkUpdate); + _eventsManager.Register(SdkEvent.SdkReady, TriggerSdkReady); + _eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(new Dictionary())); - SdkUpdate = false; + SdkUpdateFlag = false; _cache.Update(toAdd, new List(), -1); // Act. @@ -208,7 +206,7 @@ public async Task NotifyUpdateEventTest() // Assert. Assert.AreEqual(5, result.Count); - Assert.IsTrue(SdkUpdate); + Assert.IsTrue(SdkUpdateFlag); Assert.IsTrue(eMetadata.ContainKey(Splitio.Constants.EventMetadataKeys.Flags)); List flags = (List)eMetadata.GetData()[Splitio.Constants.EventMetadataKeys.Flags]; Assert.IsTrue(flags.Count == 5); @@ -217,11 +215,11 @@ public async Task NotifyUpdateEventTest() Assert.IsTrue(flags.Contains($"feature-flag-{i}")); } - SdkUpdate = false; + SdkUpdateFlag = false; eMetadata = null; _cache.Kill(123, "feature-flag-1", "off"); - Assert.IsTrue(SdkUpdate); + Assert.IsTrue(SdkUpdateFlag); Assert.IsTrue(eMetadata.ContainKey(Splitio.Constants.EventMetadataKeys.Flags)); flags = (List)eMetadata.GetData()[Splitio.Constants.EventMetadataKeys.Flags]; Assert.IsTrue(flags.Count == 1); @@ -230,8 +228,18 @@ public async Task NotifyUpdateEventTest() private void sdkUpdate_callback(object sender, EventMetadata metadata) { - SdkUpdate = true; + SdkUpdateFlag = true; eMetadata = metadata; } + + private void TriggerSdkReady(EventMetadata metaData) + { + SdkReady?.Invoke(this, metaData); + } + + private void TriggerSdkUpdate(EventMetadata metaData) + { + SdkUpdate?.Invoke(this, metaData); + } } } diff --git a/tests/Splitio-tests/Unit Tests/Cache/InMemory/SplitCacheTests.cs b/tests/Splitio-tests/Unit Tests/Cache/InMemory/SplitCacheTests.cs index 35a59f451..651f66ee3 100644 --- a/tests/Splitio-tests/Unit Tests/Cache/InMemory/SplitCacheTests.cs +++ b/tests/Splitio-tests/Unit Tests/Cache/InMemory/SplitCacheTests.cs @@ -15,9 +15,10 @@ namespace Splitio_Tests.Unit_Tests.Cache public class SplitCacheTests { private readonly Mock _flagSetsFilter; - private bool SdkUpdate = false; + private bool SdkUpdateFlag = false; private EventMetadata eMetadata = null; - public event EventHandler PublicSdkUpdateHandler; + public event EventHandler SdkUpdate; + public event EventHandler SdkReady; public SplitCacheTests() { @@ -28,8 +29,8 @@ public SplitCacheTests() public void AddAndGetSplitTest() { //Arrange - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager.Object); var splitName = "test1"; //Act @@ -44,8 +45,8 @@ public void AddAndGetSplitTest() public void AddDuplicateSplitTest() { //Arrange - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager.Object); var splitName = "test1"; //Act @@ -65,8 +66,8 @@ public void AddDuplicateSplitTest() public void GetInexistentSplitTest() { //Arrange - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager.Object); var splitName = "test1"; //Act @@ -83,8 +84,8 @@ public void RemoveSplitTest() var splitName = "test1"; var splits = new ConcurrentDictionary(); splits.TryAdd(splitName, new ParsedSplit() { name = splitName }); - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(splits, _flagSetsFilter.Object, eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(splits, _flagSetsFilter.Object, eventsManager.Object); //Act splitCache.Update(new List(), new List { splitName }, -1); @@ -98,8 +99,8 @@ public void RemoveSplitTest() public void SetAndGetChangeNumberTest() { //Arrange - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager.Object); var changeNumber = 1234; //Act @@ -114,8 +115,8 @@ public void SetAndGetChangeNumberTest() public void GetAllSplitsTest() { //Arrange - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager.Object); var splitName = "test1"; var splitName2 = "test2"; @@ -134,8 +135,8 @@ public void GetAllSplitsTest() public void AddOrUpdate_WhenUpdateTraffictType_ReturnsTrue() { // Arrange - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager.Object); var splitName = "split_1"; var splitName2 = "split_2"; @@ -177,8 +178,8 @@ public void GetNamesByFlagSetsWithoutFilter() Sets = new HashSet { "set1", "set2" } }); - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(featureFlags, new FlagSetsFilter(new HashSet()), eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(featureFlags, new FlagSetsFilter(new HashSet()), eventsManager.Object); var flagSetNames = new List { "set1", "set2", "set3", "set4" }; // Act. @@ -221,8 +222,8 @@ public void GetNamesByFlagSetsWithFilters() defaultTreatment = "on", Sets = new HashSet { "set1", "set2" } }); - var eventsManager = new EventsManager(new EventsManagerConfig()); - var splitCache = new InMemorySplitCache(featureFlags, new FlagSetsFilter(new HashSet() { "set1", "set2" }), eventsManager); + Mock> eventsManager = new Mock>(); + var splitCache = new InMemorySplitCache(featureFlags, new FlagSetsFilter(new HashSet() { "set1", "set2" }), eventsManager.Object); var flagSetNames = new List { "set1", "set2", "set3", "set4" }; // Act. @@ -244,36 +245,34 @@ public void GetNamesByFlagSetsWithFilters() public void NotifyUpdateEventTest() { // Arrange. - var eventsManager = new EventsManager(new EventsManagerConfig()); - Splitio.Util.Helper.BuildInternalSdkEventStatus(eventsManager); + var eventsManager = new EventsManager(new EventsManagerConfig(), new EventDelivery()); var splitCache = new InMemorySplitCache(new ConcurrentDictionary(), _flagSetsFilter.Object, eventsManager); var splitName = "test1"; var toNotify = new List { { splitName } }; - PublicSdkUpdateHandler += sdkUpdate_callback; - eventsManager.Register(SdkEvent.SdkUpdate, sdkUpdate_callback); - eventsManager.Register(SdkEvent.SdkReady, sdkUpdate_callback); - eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(new Dictionary()), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.SdkReady, eventsManager)); + SdkUpdate += sdkUpdate_callback; + eventsManager.Register(SdkEvent.SdkUpdate, TriggerSdkUpdate); + eventsManager.Register(SdkEvent.SdkReady, TriggerSdkReady); + eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(new Dictionary())); // Act. - SdkUpdate = false; + SdkUpdateFlag = false; splitCache.Update(new List { new ParsedSplit() { name = splitName } }, new List(), -1); // Assert. - Assert.IsTrue(SdkUpdate); + Assert.IsTrue(SdkUpdateFlag); Assert.IsTrue(eMetadata.ContainKey(Splitio.Constants.EventMetadataKeys.Flags)); List flags = (List)eMetadata.GetData()[Splitio.Constants.EventMetadataKeys.Flags]; Assert.IsTrue(flags.Count == 1); Assert.IsTrue(flags.Contains(splitName)); // Act. - SdkUpdate = false; + SdkUpdateFlag = false; eMetadata = null; splitCache.Kill(123, splitName, "off"); // Assert. - Assert.IsTrue(SdkUpdate); + Assert.IsTrue(SdkUpdateFlag); Assert.IsTrue(eMetadata.ContainKey(Splitio.Constants.EventMetadataKeys.Flags)); flags = (List)eMetadata.GetData()[Splitio.Constants.EventMetadataKeys.Flags]; Assert.IsTrue(flags.Count == 1); @@ -282,8 +281,18 @@ public void NotifyUpdateEventTest() private void sdkUpdate_callback(object sender, EventMetadata metadata) { - SdkUpdate = true; + SdkUpdateFlag = true; eMetadata = metadata; } + + private void TriggerSdkReady(EventMetadata metaData) + { + SdkReady?.Invoke(this, metaData); + } + + private void TriggerSdkUpdate(EventMetadata metaData) + { + SdkUpdate?.Invoke(this, metaData); + } } } diff --git a/tests/Splitio-tests/Unit Tests/Common/EventDeliveryTests.cs b/tests/Splitio-tests/Unit Tests/Common/EventDeliveryTests.cs index 807110872..1619f9d17 100644 --- a/tests/Splitio-tests/Unit Tests/Common/EventDeliveryTests.cs +++ b/tests/Splitio-tests/Unit Tests/Common/EventDeliveryTests.cs @@ -1,7 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Splitio.Domain; using Splitio.Services.Common; -using System; using System.Collections.Generic; namespace Splitio_Tests.Unit_Tests.Common @@ -11,7 +10,6 @@ public class EventDeliveryTests { private bool SdkReady = false; private EventMetadata eMetadata = null; - public event EventHandler PublicSdkReadyHandler; [TestMethod] public void TestFiringEvents() @@ -19,14 +17,12 @@ public void TestFiringEvents() //Act EventDelivery eventDelivery = new EventDelivery(); - PublicSdkReadyHandler += sdkReady_callback; - Dictionary metaData = new Dictionary { { "flags", new List {{ "flag1" }} } }; - eventDelivery.Deliver(SdkEvent.SdkReady, new EventMetadata(metaData), PublicSdkReadyHandler); + eventDelivery.Deliver(SdkEvent.SdkReady, new EventMetadata(metaData), sdkReady_callback); Assert.IsTrue(SdkReady); VerifyMetadata(eMetadata); @@ -40,7 +36,7 @@ void VerifyMetadata(EventMetadata eMetdata) Assert.IsTrue(flags.Contains("flag1")); } - private void sdkReady_callback(object sender, EventMetadata metadata) + private void sdkReady_callback(EventMetadata metadata) { SdkReady = true; eMetadata = metadata; diff --git a/tests/Splitio-tests/Unit Tests/Common/EventsManagerTests.cs b/tests/Splitio-tests/Unit Tests/Common/EventsManagerTests.cs index 558fa68cf..5d662d98d 100644 --- a/tests/Splitio-tests/Unit Tests/Common/EventsManagerTests.cs +++ b/tests/Splitio-tests/Unit Tests/Common/EventsManagerTests.cs @@ -9,148 +9,123 @@ namespace Splitio_Tests.Unit_Tests.Common [TestClass] public class EventsManagerTests { - private bool SdkReady = false; - private bool SdkTimedOut = false; - private bool SdkUpdate = false; + private bool SdkReadyFlag = false; + private bool SdkReadyFlag2 = false; + private bool SdkTimedOutFlag = false; + private bool SdkUpdateFlag = false; private EventMetadata eMetadata = null; - public event EventHandler PublicSdkReadyHandler; - public event EventHandler PublicSdkUpdateHandler; - public event EventHandler PublicSdkTimedOutHandler; + public event EventHandler SdkReady; + public event EventHandler SdkUpdate; + public event EventHandler SdkTimedOut; [TestMethod] public void TestFiringEvents() { //Act EventsManagerConfig config = new EventsManagerConfig(); - EventsManager eventsManager = new EventsManager(config); - Splitio.Util.Helper.BuildInternalSdkEventStatus(eventsManager); - - PublicSdkReadyHandler += sdkReady_callback; - PublicSdkUpdateHandler += sdkUpdate_callback; - PublicSdkTimedOutHandler += sdkTimedOut_callback; + EventsManager eventsManager = new EventsManager(config, new EventDelivery()); + SdkReady += sdkReady_callback; + SdkReady += sdkReady_callback2; + SdkUpdate += sdkUpdate_callback; + SdkTimedOut += sdkTimedOut_callback; Dictionary metaData = new Dictionary { { "flags", new List {{ "flag1" }} } }; - eventsManager.Register(SdkEvent.SdkReady, sdkReady_callback); - eventsManager.Register(SdkEvent.SdkUpdate, sdkUpdate_callback); - - eventsManager.NotifyInternalEvent(SdkInternalEvent.RuleBasedSegmentsUpdated, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.RuleBasedSegmentsUpdated, - eventsManager)); - eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagKilledNotification, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.FlagKilledNotification, - eventsManager)); - eventsManager.NotifyInternalEvent(SdkInternalEvent.SegmentsUpdated, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.SegmentsUpdated, - eventsManager)); - eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagsUpdated, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.FlagsUpdated, - eventsManager)); - Assert.IsFalse(SdkReady); - Assert.IsFalse(SdkUpdate); - Assert.IsFalse(SdkTimedOut); + eventsManager.Register(SdkEvent.SdkReady, TriggerSdkReady); + eventsManager.Register(SdkEvent.SdkUpdate, TriggerSdkUpdate); + + eventsManager.NotifyInternalEvent(SdkInternalEvent.RuleBasedSegmentsUpdated, new EventMetadata(metaData)); + eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagKilledNotification, new EventMetadata(metaData)); + eventsManager.NotifyInternalEvent(SdkInternalEvent.SegmentsUpdated, new EventMetadata(metaData)); + eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagsUpdated, new EventMetadata(metaData)); + Assert.IsFalse(SdkReadyFlag); + Assert.IsFalse(SdkUpdateFlag); + Assert.IsFalse(SdkTimedOutFlag); ResetAllVariables(); - eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkTimedOut, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.SdkTimedOut, - eventsManager)); - System.Threading.SpinWait.SpinUntil(() => SdkTimedOut, TimeSpan.FromMilliseconds(500)); - Assert.IsFalse(SdkReady); - Assert.IsFalse(SdkUpdate); - Assert.IsFalse(SdkTimedOut); // not fired as it is not registered yet - - eventsManager.Register(SdkEvent.SdkReadyTimeout, sdkTimedOut_callback); - eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkTimedOut, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.SdkTimedOut, - eventsManager)); - System.Threading.SpinWait.SpinUntil(() => SdkTimedOut, TimeSpan.FromMilliseconds(500)); - Assert.IsFalse(SdkReady); - Assert.IsFalse(SdkUpdate); - Assert.IsTrue(SdkTimedOut); + eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkTimedOut, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkTimedOutFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsFalse(SdkReadyFlag); + Assert.IsFalse(SdkUpdateFlag); + Assert.IsFalse(SdkTimedOutFlag); // not fired as it is not registered yet + + eventsManager.Register(SdkEvent.SdkReadyTimeout, TriggerSdkTimeout); + eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkTimedOut, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkTimedOutFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsFalse(SdkReadyFlag); + Assert.IsFalse(SdkUpdateFlag); + Assert.IsTrue(SdkTimedOutFlag); VerifyMetadata(eMetadata); ResetAllVariables(); - List eventsToNotify = Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.SdkReady, - eventsManager); - eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(metaData), - eventsToNotify); - System.Threading.SpinWait.SpinUntil(() => SdkReady, TimeSpan.FromMilliseconds(500)); - Assert.IsTrue(SdkReady); - Assert.IsFalse(SdkUpdate); - Assert.IsFalse(SdkTimedOut); + eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkReady, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkReadyFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsTrue(SdkReadyFlag); + Assert.IsTrue(SdkReadyFlag2); + Assert.IsFalse(SdkUpdateFlag); + Assert.IsFalse(SdkTimedOutFlag); VerifyMetadata(eMetadata); ResetAllVariables(); - eventsManager.Register(SdkEvent.SdkReadyTimeout, sdkTimedOut_callback); - eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkTimedOut, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.SdkTimedOut, - eventsManager)); - System.Threading.SpinWait.SpinUntil(() => SdkTimedOut, TimeSpan.FromMilliseconds(500)); - Assert.IsFalse(SdkReady); - Assert.IsFalse(SdkUpdate); - Assert.IsFalse(SdkTimedOut); // not fired as suppressed by sdkReady + eventsManager.Register(SdkEvent.SdkReadyTimeout, TriggerSdkTimeout); + eventsManager.NotifyInternalEvent(SdkInternalEvent.SdkTimedOut, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkTimedOutFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsFalse(SdkReadyFlag); + Assert.IsFalse(SdkUpdateFlag); + Assert.IsFalse(SdkTimedOutFlag); // not fired as suppressed by sdkReady ResetAllVariables(); - eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagKilledNotification, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.FlagKilledNotification, - eventsManager)); - System.Threading.SpinWait.SpinUntil(() => SdkUpdate, TimeSpan.FromMilliseconds(500)); - Assert.IsFalse(SdkTimedOut); - Assert.IsFalse(SdkReady); - Assert.IsTrue(SdkUpdate); + eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagKilledNotification, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkUpdateFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsFalse(SdkTimedOutFlag); + Assert.IsFalse(SdkReadyFlag); + Assert.IsTrue(SdkUpdateFlag); VerifyMetadata(eMetadata); ResetAllVariables(); - eventsManager.NotifyInternalEvent(SdkInternalEvent.SegmentsUpdated, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.SegmentsUpdated, - eventsManager)); - System.Threading.SpinWait.SpinUntil(() => SdkUpdate, TimeSpan.FromMilliseconds(500)); - Assert.IsFalse(SdkTimedOut); - Assert.IsFalse(SdkReady); - Assert.IsTrue(SdkUpdate); + eventsManager.NotifyInternalEvent(SdkInternalEvent.SegmentsUpdated, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkUpdateFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsFalse(SdkTimedOutFlag); + Assert.IsFalse(SdkReadyFlag); + Assert.IsTrue(SdkUpdateFlag); VerifyMetadata(eMetadata); ResetAllVariables(); - eventsManager.NotifyInternalEvent(SdkInternalEvent.RuleBasedSegmentsUpdated, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.RuleBasedSegmentsUpdated, - eventsManager)); - System.Threading.SpinWait.SpinUntil(() => SdkUpdate, TimeSpan.FromMilliseconds(500)); - Assert.IsFalse(SdkTimedOut); - Assert.IsFalse(SdkReady); - Assert.IsTrue(SdkUpdate); + eventsManager.NotifyInternalEvent(SdkInternalEvent.RuleBasedSegmentsUpdated, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkUpdateFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsFalse(SdkTimedOutFlag); + Assert.IsFalse(SdkReadyFlag); + Assert.IsTrue(SdkUpdateFlag); VerifyMetadata(eMetadata); ResetAllVariables(); - eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagsUpdated, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.FlagsUpdated, - eventsManager)); - System.Threading.SpinWait.SpinUntil(() => SdkUpdate, TimeSpan.FromMilliseconds(500)); - Assert.IsFalse(SdkTimedOut); - Assert.IsFalse(SdkReady); - Assert.IsTrue(SdkUpdate); + eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagsUpdated, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkUpdateFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsFalse(SdkTimedOutFlag); + Assert.IsFalse(SdkReadyFlag); + Assert.IsTrue(SdkUpdateFlag); VerifyMetadata(eMetadata); eventsManager.Unregister(SdkEvent.SdkUpdate); eventsManager.Unregister(SdkEvent.SdkUpdate); // should not cause exception ResetAllVariables(); - eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagsUpdated, new EventMetadata(metaData), - Splitio.Util.Helper.GetSdkEventIfApplicable(SdkInternalEvent.FlagsUpdated, - eventsManager)); - System.Threading.SpinWait.SpinUntil(() => SdkUpdate, TimeSpan.FromMilliseconds(500)); - Assert.IsFalse(SdkTimedOut); - Assert.IsFalse(SdkReady); - Assert.IsFalse(SdkUpdate); + eventsManager.NotifyInternalEvent(SdkInternalEvent.FlagsUpdated, new EventMetadata(metaData)); + System.Threading.SpinWait.SpinUntil(() => SdkUpdateFlag, TimeSpan.FromMilliseconds(500)); + Assert.IsFalse(SdkTimedOutFlag); + Assert.IsFalse(SdkReadyFlag); + Assert.IsFalse(SdkUpdateFlag); } void ResetAllVariables() { - SdkReady = false; - SdkTimedOut = false; + SdkReadyFlag = false; + SdkReadyFlag2 = false; + SdkTimedOutFlag = false; eMetadata = null; - SdkUpdate = false; + SdkUpdateFlag = false; } void VerifyMetadata(EventMetadata eMetdata) @@ -163,20 +138,42 @@ void VerifyMetadata(EventMetadata eMetdata) private void sdkUpdate_callback(object sender, EventMetadata metadata) { - SdkUpdate = true; + SdkUpdateFlag = true; eMetadata = metadata; } private void sdkReady_callback(object sender, EventMetadata metadata) { - SdkReady = true; + SdkReadyFlag = true; + eMetadata = metadata; + } + + private void sdkReady_callback2(object sender, EventMetadata metadata) + { + SdkReadyFlag2 = true; eMetadata = metadata; } private void sdkTimedOut_callback(object sender, EventMetadata metadata) { - SdkTimedOut = true; + SdkTimedOutFlag = true; eMetadata = metadata; } + + private void TriggerSdkReady(EventMetadata metaData) + { + SdkReady?.Invoke(this, metaData); + } + + private void TriggerSdkUpdate(EventMetadata metaData) + { + SdkUpdate?.Invoke(this, metaData); + } + + private void TriggerSdkTimeout(EventMetadata metaData) + { + SdkTimedOut?.Invoke(this, metaData); + } + } } diff --git a/tests/Splitio-tests/Unit Tests/Matchers/UserDefinedSegmentMatcherAsyncTests.cs b/tests/Splitio-tests/Unit Tests/Matchers/UserDefinedSegmentMatcherAsyncTests.cs index 1a7a087ff..f3a0ff0ea 100644 --- a/tests/Splitio-tests/Unit Tests/Matchers/UserDefinedSegmentMatcherAsyncTests.cs +++ b/tests/Splitio-tests/Unit Tests/Matchers/UserDefinedSegmentMatcherAsyncTests.cs @@ -1,6 +1,8 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; using Splitio.Domain; using Splitio.Services.Cache.Classes; +using Splitio.Services.Common; using Splitio.Services.Parsing; using System.Collections.Concurrent; using System.Collections.Generic; @@ -22,7 +24,8 @@ public async Task MatchAsyncShouldReturnTrueOnMatchingSegmentWithKey() }; var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, keys); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -45,7 +48,8 @@ public async Task MatchAsyncShouldReturnFalseOnNonMatchingSegmentWithKey() }; var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, keys); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -62,7 +66,8 @@ public async Task MatchAsyncShouldReturnFalseIfSegmentEmptyWithKey() { //Arrange var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, null); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -79,7 +84,8 @@ public async Task MatchAsyncShouldReturnFalseIfCacheEmptyWithKey() { //Arrange var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -101,7 +107,8 @@ public async Task MatchAsyncShouldReturnTrueOnMatchingSegment() }; var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, keys); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -124,7 +131,8 @@ public async Task MatchAsyncShouldReturnFalseOnNonMatchingSegment() }; var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, keys); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -141,7 +149,8 @@ public async Task MatchAsyncShouldReturnFalseIfSegmentEmpty() { //Arrange var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, null); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -158,7 +167,8 @@ public async Task MatchAsyncShouldReturnFalseIfCacheEmpty() { //Arrange var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); diff --git a/tests/Splitio-tests/Unit Tests/Matchers/UserDefinedSegmentMatcherTests.cs b/tests/Splitio-tests/Unit Tests/Matchers/UserDefinedSegmentMatcherTests.cs index e35113990..f7c1245c4 100644 --- a/tests/Splitio-tests/Unit Tests/Matchers/UserDefinedSegmentMatcherTests.cs +++ b/tests/Splitio-tests/Unit Tests/Matchers/UserDefinedSegmentMatcherTests.cs @@ -1,9 +1,11 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using Splitio.Services.Parsing; +using Moq; using Splitio.Domain; -using System.Collections.Generic; -using System.Collections.Concurrent; using Splitio.Services.Cache.Classes; +using Splitio.Services.Common; +using Splitio.Services.Parsing; +using System.Collections.Concurrent; +using System.Collections.Generic; namespace Splitio_Tests.Unit_Tests { @@ -21,7 +23,8 @@ public void MatchShouldReturnTrueOnMatchingSegmentWithKey() }; var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, keys); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -44,7 +47,8 @@ public void MatchShouldReturnFalseOnNonMatchingSegmentWithKey() }; var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, keys); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -61,7 +65,8 @@ public void MatchShouldReturnFalseIfSegmentEmptyWithKey() { //Arrange var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, null); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -78,7 +83,8 @@ public void MatchShouldReturnFalseIfCacheEmptyWithKey() { //Arrange var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -100,7 +106,8 @@ public void MatchShouldReturnTrueOnMatchingSegment() }; var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, keys); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -123,7 +130,8 @@ public void MatchShouldReturnFalseOnNonMatchingSegment() }; var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, keys); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -140,7 +148,8 @@ public void MatchShouldReturnFalseIfSegmentEmpty() { //Arrange var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); segmentCache.AddToSegment(segmentName, null); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); @@ -157,7 +166,8 @@ public void MatchShouldReturnFalseIfCacheEmpty() { //Arrange var segmentName = "test-segment"; - var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary()); + Mock> eventsManager = new Mock>(); + var segmentCache = new InMemorySegmentCache(new ConcurrentDictionary(), eventsManager.Object); var matcher = new UserDefinedSegmentMatcher(segmentName, segmentCache); diff --git a/tests/Splitio-tests/Unit Tests/SegmentFetcher/SelfRefreshingSegmentFetcherUnitTests.cs b/tests/Splitio-tests/Unit Tests/SegmentFetcher/SelfRefreshingSegmentFetcherUnitTests.cs index b2eac5b97..e16e8ca3d 100644 --- a/tests/Splitio-tests/Unit Tests/SegmentFetcher/SelfRefreshingSegmentFetcherUnitTests.cs +++ b/tests/Splitio-tests/Unit Tests/SegmentFetcher/SelfRefreshingSegmentFetcherUnitTests.cs @@ -4,6 +4,7 @@ using Splitio.Services.Cache.Classes; using Splitio.Services.Cache.Interfaces; using Splitio.Services.Client.Classes; +using Splitio.Services.Common; using Splitio.Services.SegmentFetcher.Classes; using Splitio.Services.SegmentFetcher.Interfaces; using Splitio.Services.Shared.Classes; @@ -31,7 +32,8 @@ public void InitializeSegmentNotExistent() var apiClient = new Mock(); var apiFetcher = new ApiSegmentChangeFetcher(apiClient.Object); var segments = new ConcurrentDictionary(); - var cache = new InMemorySegmentCache(segments); + Mock> eventsManager = new Mock>(); + var cache = new InMemorySegmentCache(segments, eventsManager.Object); var segmentsQueue = new SplitQueue(); var taskManager = new TasksManager(gates); var worker = new SegmentTaskWorker(5, segmentsQueue); diff --git a/tests/Splitio-tests/Unit Tests/SegmentFetcher/SelfRefreshingSegmentUnitTests.cs b/tests/Splitio-tests/Unit Tests/SegmentFetcher/SelfRefreshingSegmentUnitTests.cs index 228dc4c59..830745586 100644 --- a/tests/Splitio-tests/Unit Tests/SegmentFetcher/SelfRefreshingSegmentUnitTests.cs +++ b/tests/Splitio-tests/Unit Tests/SegmentFetcher/SelfRefreshingSegmentUnitTests.cs @@ -3,6 +3,7 @@ using Splitio.Domain; using Splitio.Services.Cache.Classes; using Splitio.Services.Cache.Interfaces; +using Splitio.Services.Common; using Splitio.Services.SegmentFetcher.Classes; using Splitio.Services.SplitFetcher.Interfaces; using System; @@ -22,7 +23,8 @@ public async Task FetchSegmentNullChangesFetcherResponseShouldNotUpdateCache() var statusManager = new Mock(); var apiFetcher = new ApiSegmentChangeFetcher(apiClient.Object); var segments = new ConcurrentDictionary(); - var cache = new InMemorySegmentCache(segments); + Mock> eventsManager = new Mock>(); + var cache = new InMemorySegmentCache(segments, eventsManager.Object); var segmentFetcher = new SelfRefreshingSegment("payed", apiFetcher, cache, statusManager.Object); apiClient @@ -44,7 +46,8 @@ public async Task FetchSegmentShouldUpdateSegmentsCache() var statusManager = new Mock(); var apiFetcher = new ApiSegmentChangeFetcher(apiClient.Object); var segments = new ConcurrentDictionary(); - var cache = new InMemorySegmentCache(segments); + Mock> eventsManager = new Mock>(); + var cache = new InMemorySegmentCache(segments, eventsManager.Object); var segmentFetcher = new SelfRefreshingSegment("payed", apiFetcher, cache, statusManager.Object); apiClient