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));
        }
Пример #7
0
        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);
        }
Пример #8
0
        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));
        }
Пример #9
0
        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);
            }
        }