private static ItemDescriptor DeserializeSegment(ref JReader r) { var segment = SegmentSerialization.Instance.ReadJson(ref r) as Segment; return(segment.Deleted ? ItemDescriptor.Deleted(segment.Version) : new ItemDescriptor(segment.Version, segment)); }
private static ItemDescriptor DeserializeFlag(ref JReader r) { var flag = FeatureFlagSerialization.Instance.ReadJson(ref r) as FeatureFlag; return(flag.Deleted ? ItemDescriptor.Deleted(flag.Version) : new ItemDescriptor(flag.Version, flag)); }
public void GetAllDoesNotRemoveDeletedItems(TestParams testParams) { var wrapper = MakeWrapper(testParams); var itemA = new TestItem("itemA"); _core.ForceSet(TestDataKind, "keyA", 1, itemA); _core.ForceSet(TestDataKind, "keyB", 2, null); // deleted item var items = wrapper.GetAll(TestDataKind).Items.ToDictionary(kv => kv.Key, kv => kv.Value); var expected = ImmutableDictionary.Create <string, ItemDescriptor>() .Add("keyA", itemA.WithVersion(1)) .Add("keyB", ItemDescriptor.Deleted(2)); Assert.Equal(expected, items); }
public void GetDeletedItem(TestParams testParams) { var wrapper = MakeWrapper(testParams); var key = "flag"; var itemv2 = new TestItem("itemv2"); _core.ForceSet(TestDataKind, key, 1, null); Assert.Equal(new ItemDescriptor(1, null), wrapper.Get(TestDataKind, key)); _core.ForceSet(TestDataKind, key, 2, itemv2); var result = wrapper.Get(TestDataKind, key); // if cached, we will not see the new underlying value yet Assert.Equal(testParams.CacheMode.IsUncached ? itemv2.WithVersion(2) : ItemDescriptor.Deleted(1), result); }
public void SerializeDeletedItems() { // It's important that the SDK provides a placeholder JSON object for deleted items, because some // of our existing database integrations aren't able to store the version number separately from // the JSON data. var deletedItem = ItemDescriptor.Deleted(2); var expected = LdValue.BuildObject().Add("version", 2).Add("deleted", true).Build().ToJsonString(); var s1 = DataModel.Features.Serialize(deletedItem); AssertJsonEqual(expected, s1); var s2 = DataModel.Segments.Serialize(deletedItem); AssertJsonEqual(expected, s2); }
private ItemDescriptor Deserialize(DataKind kind, SerializedItemDescriptor serializedItemDesc) { if (serializedItemDesc.Deleted || serializedItemDesc.SerializedItem is null) { return(ItemDescriptor.Deleted(serializedItemDesc.Version)); } var deserializedItem = kind.Deserialize(serializedItemDesc.SerializedItem); if (serializedItemDesc.Version == 0 || serializedItemDesc.Version == deserializedItem.Version || deserializedItem.Item is null) { return(deserializedItem); } // If the store gave us a version number that isn't what was encoded in the object, trust it return(new ItemDescriptor(serializedItemDesc.Version, deserializedItem.Item)); }
public void SendsEventOnUpdateForDeletedFlag() { var dataBuilder = new DataSetBuilder().Flags(flag1, flag2).Segments(segment1); var updates = MakeInstance(); updates.Init(dataBuilder.Build()); var eventSink = new EventSink <FlagChangeEvent>(); updates.FlagChanged += eventSink.Add; updates.Upsert(DataModel.Features, flag2.Key, ItemDescriptor.Deleted(flag2v2.Version)); ExpectFlagChangeEvents(eventSink, flag2.Key); }
public void DeleteDeletesSegment() { StreamProcessor sp = CreateAndStartProcessor(); SimulateMessageReceived("put", EmptyPutData); TestUtils.UpsertSegment(_dataStore, SEGMENT); string path = "/segments/" + SEGMENT_KEY; int deletedVersion = SEGMENT.Version + 1; string data = LdValue.BuildObject() .Add("path", path) .Add("version", deletedVersion) .Build().ToJsonString(); SimulateMessageReceived("delete", data); Assert.Equal(ItemDescriptor.Deleted(deletedVersion), _dataStore.Get(DataModel.Segments, SEGMENT_KEY)); }
public void DeleteDeletesFeature() { StreamProcessor sp = CreateAndStartProcessor(); SimulateMessageReceived("put", EmptyPutData); TestUtils.UpsertFlag(_dataStore, FEATURE); string path = "/flags/" + FEATURE_KEY; int deletedVersion = FEATURE.Version + 1; string data = LdValue.BuildObject() .Add("path", path) .Add("version", deletedVersion) .Build().ToJsonString(); SimulateMessageReceived("delete", data); Assert.Equal(ItemDescriptor.Deleted(deletedVersion), _dataStore.Get(DataModel.Features, FEATURE_KEY)); }
public void CachedAllUsesValuesFromInit() { var wrapper = MakeWrapper(Cached); var itemA = new TestItem("itemA"); var allData = new TestDataBuilder() .Add(TestDataKind, "keyA", 1, itemA) .Add(TestDataKind, "keyB", 2, null) // deleted item .Build(); wrapper.Init(allData); _core.ForceRemove(TestDataKind, "keyA"); var items = wrapper.GetAll(TestDataKind).Items.ToDictionary(kv => kv.Key, kv => kv.Value); var expected = ImmutableDictionary.Create <string, ItemDescriptor>() .Add("keyA", itemA.WithVersion(1)) .Add("keyB", ItemDescriptor.Deleted(2)); Assert.Equal(expected, items); }
private void CauseStoreError(MockCoreBase core, PersistentStoreWrapper wrapper) { core.Available = false; core.Error = FakeError; Assert.Equal(FakeError, Assert.Throws(FakeError.GetType(), () => wrapper.Upsert(TestDataKind, "irrelevant-key", ItemDescriptor.Deleted(1)))); }
public void LdClientEndToEndTests() { // This is a basic smoke test to verify that the data store component behaves correctly within an // SDK client instance. var flag = FlagTestData.MakeFlagThatReturnsVariationForSegmentMatch(1, FlagTestData.GoodVariation1); var segment = FlagTestData.MakeSegmentThatMatchesUserKeys(1, FlagTestData.UserKey); var data = FlagTestData.MakeFullDataSet(flag, segment); var dataSourceFactory = new TestDataSourceFactory(data); var clientConfig = LaunchDarkly.Sdk.Server.Configuration.Builder("sdk-key") .DataSource(dataSourceFactory) .Events(Components.NoEvents) .Logging(Components.Logging(_testLogging)); if (Configuration.StoreFactoryFunc != null) { clientConfig.DataStore(Components.PersistentDataStore(Configuration.StoreFactoryFunc(null))); } else if (Configuration.StoreAsyncFactoryFunc != null) { clientConfig.DataStore(Components.PersistentDataStore(Configuration.StoreAsyncFactoryFunc(null))); } else { throw new InvalidOperationException("neither StoreFactoryFunc nor StoreAsyncFactoryFunc was set"); } using (var client = new LdClient(clientConfig.Build())) { var dataSourceUpdates = dataSourceFactory._updates; Action <User, LdValue> flagShouldHaveValueForUser = (user, value) => Assert.Equal(value, client.JsonVariation(FlagTestData.FlagKey, user, LdValue.Null)); // evaluate each flag from the data store flagShouldHaveValueForUser(FlagTestData.MainUser, FlagTestData.GoodValue1); flagShouldHaveValueForUser(FlagTestData.OtherUser, FlagTestData.BadValue); // evaluate all flags var state = client.AllFlagsState(FlagTestData.MainUser); Assert.Equal(FlagTestData.GoodValue1, state.GetFlagValueJson(FlagTestData.FlagKey)); // update the flag var flagV2 = FlagTestData.MakeFlagThatReturnsVariationForSegmentMatch(2, FlagTestData.GoodVariation2); dataSourceUpdates.Upsert(DataModel.Features, FlagTestData.FlagKey, flagV2); // flag should now return new value flagShouldHaveValueForUser(FlagTestData.MainUser, FlagTestData.GoodValue2); flagShouldHaveValueForUser(FlagTestData.OtherUser, FlagTestData.BadValue); // update the segment so it now matches both users var segmentV2 = FlagTestData.MakeSegmentThatMatchesUserKeys(2, FlagTestData.UserKey, FlagTestData.OtherUserKey); dataSourceUpdates.Upsert(DataModel.Segments, FlagTestData.SegmentKey, segmentV2); flagShouldHaveValueForUser(FlagTestData.MainUser, FlagTestData.GoodValue2); flagShouldHaveValueForUser(FlagTestData.OtherUser, FlagTestData.GoodValue2); // delete the segment - should cause the flag that uses it to stop matching dataSourceUpdates.Upsert(DataModel.Segments, FlagTestData.SegmentKey, ItemDescriptor.Deleted(3)); flagShouldHaveValueForUser(FlagTestData.MainUser, FlagTestData.BadValue); flagShouldHaveValueForUser(FlagTestData.OtherUser, FlagTestData.BadValue); // delete the flag so it becomes unknown dataSourceUpdates.Upsert(DataModel.Features, FlagTestData.FlagKey, ItemDescriptor.Deleted(3)); var detail = client.JsonVariationDetail(FlagTestData.FlagKey, FlagTestData.MainUser, LdValue.Null); Assert.Equal(EvaluationReason.ErrorReason(EvaluationErrorKind.FlagNotFound), detail.Reason); } }