public void DebugModeExpiresBasedOnServerTimeIfServerTimeIsLaterThanClientTime()
        {
            _ep = MakeProcessor(_config);

            // Pick a server time that is somewhat ahead of the client time
            long serverTime = Util.GetUnixTimestampMillis(DateTime.Now) + 20000;

            // Send and flush an event we don't care about, just to set the last server time
            _ep.SendEvent(EventFactory.Default.NewIdentifyEvent(User.WithKey("otherUser")));
            FlushAndGetEvents(AddDateHeader(OkResponse(), serverTime));

            // Now send an event with debug mode on, with a "debug until" time that is further in
            // the future than the client time, but in the past compared to the server.
            long debugUntil           = serverTime - 1000;
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).DebugEventsUntilDate(debugUntil).Build();
            FeatureRequestEvent  fe   = EventFactory.Default.NewFeatureRequestEvent(flag, _user,
                                                                                    new EvaluationDetail <LdValue>(LdValue.Of("value"), 1, null), LdValue.Null);

            _ep.SendEvent(fe);

            // Should get a summary event only, not a full feature event
            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckIndexEvent(item, fe, _userJson),
                              item => CheckSummaryEvent(item));
        }
        public void FeatureEventCanHaveReason()
        {
            _config.InlineUsersInEvents = true;
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).TrackEvents(true).Build();
            var reasons = new EvaluationReason[]
            {
                EvaluationReason.OffReason,
                EvaluationReason.FallthroughReason,
                EvaluationReason.TargetMatchReason,
                EvaluationReason.RuleMatchReason(1, "id"),
                EvaluationReason.PrerequisiteFailedReason("key"),
                EvaluationReason.ErrorReason(EvaluationErrorKind.WRONG_TYPE)
            };

            foreach (var reason in reasons)
            {
                FeatureRequestEvent fe = EventFactory.DefaultWithReasons.NewFeatureRequestEvent(flag, _user,
                                                                                                new EvaluationDetail <LdValue>(LdValue.Of("value"), 1, reason), LdValue.Null);
                _ep.SendEvent(fe);

                JArray output = FlushAndGetEvents(OkResponse());
                Assert.Collection(output,
                                  item => CheckFeatureEvent(item, fe, flag, false, _userJson, reason),
                                  item => CheckSummaryEvent(item));
            }
        }
예제 #3
0
        public void FeatureEventHasReasonWhenUsingFactoryWithReason()
        {
            var flag   = new FlagEventPropertiesBuilder("flag-key").Version(100).Build();
            var result = new EvaluationDetail <LdValue>(resultVal, 1, EvaluationReason.FallthroughReason);
            var e      = EventFactory.DefaultWithReasons.NewFeatureRequestEvent(flag, user, result, defaultVal);

            Assert.Equal(result.Reason, e.Reason);
        }
예제 #4
0
        public void DefaultFeatureEventHasReasonWhenUsingFactoryWithReason()
        {
            var flag = new FlagEventPropertiesBuilder("flag-key").Version(100).Build();
            var err  = EvaluationErrorKind.EXCEPTION;
            var e    = EventFactory.DefaultWithReasons.NewDefaultFeatureRequestEvent(flag, user, defaultVal, err);

            Assert.Equal(EvaluationReason.ErrorReason(err), e.Reason);
        }
예제 #5
0
        public void FeatureEventUsesTrackAndDebugPropertiesFromFlag()
        {
            var flag = new FlagEventPropertiesBuilder("flag-key").Version(100)
                       .TrackEvents(true).DebugEventsUntilDate(1000).Build();
            var result = new EvaluationDetail <LdValue>(resultVal, 1, EvaluationReason.FallthroughReason);
            var e      = EventFactory.Default.NewFeatureRequestEvent(flag, user, result, defaultVal);

            Assert.True(e.TrackEvents);
            Assert.Equal(1000, e.DebugEventsUntilDate);
        }
예제 #6
0
        public void FeatureEventHasTrackEventsAndReasonForExperiment()
        {
            var flag = new FlagEventPropertiesBuilder("flag-key").Version(100)
                       .ExperimentReason(EvaluationReason.FallthroughReason)
                       .Build();
            var result = new EvaluationDetail <LdValue>(resultVal, 1, EvaluationReason.FallthroughReason);
            var e      = EventFactory.Default.NewFeatureRequestEvent(flag, user, result, defaultVal);

            Assert.Equal(result.Reason, e.Reason);
            Assert.True(e.TrackEvents);
        }
        public void FeatureEventCanHaveNullUser()
        {
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).TrackEvents(true).Build();
            FeatureRequestEvent  fe   = EventFactory.Default.NewFeatureRequestEvent(flag, null,
                                                                                    new EvaluationDetail <LdValue>(LdValue.Of("value"), 1, null), LdValue.Null);

            _ep.SendEvent(fe);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckFeatureEvent(item, fe, flag, false, null),
                              item => CheckSummaryEvent(item));
        }
        public void IndividualFeatureEventIsQueuedWithIndexEvent()
        {
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).TrackEvents(true).Build();
            FeatureRequestEvent  fe   = EventFactory.Default.NewFeatureRequestEvent(flag, _user,
                                                                                    new EvaluationDetail <LdValue>(LdValue.Of("value"), 1, null), LdValue.Null);

            _ep.SendEvent(fe);

            var output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckIndexEvent(item, fe, _userJson),
                              item => CheckFeatureEvent(item, fe, flag, false, LdValue.Null),
                              item => CheckSummaryEvent(item));
        }
        public void FeatureEventCanContainInlineUser()
        {
            _config.InlineUsersInEvents = true;
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).TrackEvents(true).Build();
            FeatureRequestEvent  fe   = EventFactory.Default.NewFeatureRequestEvent(flag, _user,
                                                                                    1, new JValue("value"), null);

            _ep.SendEvent(fe);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckFeatureEvent(item, fe, flag, false, _userJson),
                              item => CheckSummaryEvent(item));
        }
        public void IndexEventIsStillGeneratedIfInlineUsersIsTrueButFeatureEventIsNotTracked()
        {
            _config.InlineUsersInEvents = true;
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).TrackEvents(false).Build();
            FeatureRequestEvent  fe   = EventFactory.Default.NewFeatureRequestEvent(flag, _user,
                                                                                    new EvaluationDetail <LdValue>(LdValue.Of("value"), 1, null), LdValue.Null);

            _ep.SendEvent(fe);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckIndexEvent(item, fe, _userJson),
                              item => CheckSummaryEvent(item));
        }
        public void EventKindIsDebugIfFlagIsTemporarilyInDebugMode()
        {
            _ep = MakeProcessor(_config);
            long futureTime           = Util.GetUnixTimestampMillis(DateTime.Now) + 1000000;
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).DebugEventsUntilDate(futureTime).Build();
            FeatureRequestEvent  fe   = EventFactory.Default.NewFeatureRequestEvent(flag, _user,
                                                                                    new EvaluationDetail <LdValue>(LdValue.Of("value"), 1, null), LdValue.Null);

            _ep.SendEvent(fe);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckIndexEvent(item, fe, _userJson),
                              item => CheckFeatureEvent(item, fe, flag, true, _userJson),
                              item => CheckSummaryEvent(item));
        }
        public void UserDetailsAreScrubbedInFeatureEvent()
        {
            _config.AllAttributesPrivate = true;
            _config.InlineUsersInEvents  = true;
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).TrackEvents(true).Build();
            FeatureRequestEvent  fe   = EventFactory.Default.NewFeatureRequestEvent(flag, _user,
                                                                                    new EvaluationDetail <LdValue>(LdValue.Of("value"), 1, null), LdValue.Null);

            _ep.SendEvent(fe);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckFeatureEvent(item, fe, flag, false, _scrubbedUserJson),
                              item => CheckSummaryEvent(item));
        }
예제 #13
0
        public void FeatureEventHasBasicProperties()
        {
            var time   = TimeNow();
            var flag   = new FlagEventPropertiesBuilder("flag-key").Version(100).Build();
            var result = new EvaluationDetail <LdValue>(resultVal, 1, EvaluationReason.FallthroughReason);
            var e      = EventFactory.Default.NewFeatureRequestEvent(flag, user, result, defaultVal);

            Assert.True(e.CreationDate >= time);
            Assert.Equal(flag.Key, e.Key);
            Assert.Same(user, e.User);
            Assert.Equal(flag.EventVersion, e.Version);
            Assert.Equal(result.VariationIndex, e.Variation);
            Assert.Equal(result.Value, e.Value);
            Assert.Equal(defaultVal, e.Default);
            Assert.Null(e.PrereqOf);
            Assert.Null(e.Reason);
            Assert.False(e.TrackEvents);
            Assert.Null(e.DebugEventsUntilDate);
        }
        public void EventCanBeBothTrackedAndDebugged()
        {
            _ep = MakeProcessor(_config);
            long futureTime           = Util.GetUnixTimestampMillis(DateTime.Now) + 1000000;
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("flagkey").Version(11).TrackEvents(true)
                                        .DebugEventsUntilDate(futureTime).Build();
            FeatureRequestEvent fe = EventFactory.Default.NewFeatureRequestEvent(flag, _user,
                                                                                 1, new JValue("value"), null);

            _ep.SendEvent(fe);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckIndexEvent(item, fe, _userJson),
                              item => CheckFeatureEvent(item, fe, flag, false, null),
                              item => CheckFeatureEvent(item, fe, flag, true, _userJson),
                              item => CheckSummaryEvent(item));
        }
        public void SummarizeEventSetsStartAndEndDates()
        {
            EventSummarizer      es   = new EventSummarizer();
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("key").Build();
            var   nullResult          = new EvaluationDetail <LdValue>(LdValue.Null, null, null);
            var   factory1            = new EventFactory(() => 2000, false);
            Event event1   = factory1.NewFeatureRequestEvent(flag, _user, nullResult, LdValue.Null);
            var   factory2 = new EventFactory(() => 1000, false);
            Event event2   = factory2.NewFeatureRequestEvent(flag, _user, nullResult, LdValue.Null);
            var   factory3 = new EventFactory(() => 1500, false);
            Event event3   = factory3.NewFeatureRequestEvent(flag, _user, nullResult, LdValue.Null);

            es.SummarizeEvent(event1);
            es.SummarizeEvent(event2);
            es.SummarizeEvent(event3);
            EventSummary data = es.Snapshot();

            Assert.Equal(1000, data.StartDate);
            Assert.Equal(2000, data.EndDate);
        }
        public void NonTrackedEventsAreSummarized()
        {
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag1 = new FlagEventPropertiesBuilder("flagkey1").Version(11).Build();
            IFlagEventProperties flag2 = new FlagEventPropertiesBuilder("flagkey2").Version(22).Build();
            var value1               = LdValue.Of("value1");
            var value2               = LdValue.Of("value2");
            var default1             = LdValue.Of("default1");
            var default2             = LdValue.Of("default2");
            FeatureRequestEvent fe1a = EventFactory.Default.NewFeatureRequestEvent(flag1, _user,
                                                                                   new EvaluationDetail <LdValue>(value1, 1, null), default1);
            FeatureRequestEvent fe1b = EventFactory.Default.NewFeatureRequestEvent(flag1, _user,
                                                                                   new EvaluationDetail <LdValue>(value1, 1, null), default1);
            FeatureRequestEvent fe1c = EventFactory.Default.NewFeatureRequestEvent(flag1, _user,
                                                                                   new EvaluationDetail <LdValue>(value2, 2, null), default1);
            FeatureRequestEvent fe2 = EventFactory.Default.NewFeatureRequestEvent(flag2, _user,
                                                                                  new EvaluationDetail <LdValue>(value2, 2, null), default2);

            _ep.SendEvent(fe1a);
            _ep.SendEvent(fe1b);
            _ep.SendEvent(fe1c);
            _ep.SendEvent(fe2);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckIndexEvent(item, fe1a, _userJson),
                              item => CheckSummaryEventDetails(item,
                                                               fe1a.CreationDate,
                                                               fe2.CreationDate,
                                                               MustHaveFlagSummary(flag1.Key, default1,
                                                                                   MustHaveFlagSummaryCounter(value1, 1, flag1.EventVersion, 2),
                                                                                   MustHaveFlagSummaryCounter(value2, 2, flag1.EventVersion, 1)
                                                                                   ),
                                                               MustHaveFlagSummary(flag2.Key, default2,
                                                                                   MustHaveFlagSummaryCounter(value2, 2, flag2.EventVersion, 1)
                                                                                   )
                                                               )
                              );
        }
        public void SummarizeEventSetsStartAndEndDates()
        {
            EventSummarizer      es   = new EventSummarizer();
            IFlagEventProperties flag = new FlagEventPropertiesBuilder("key").Build();

            _eventFactory.Timestamp = 2000;
            Event event1 = _eventFactory.NewFeatureRequestEvent(flag, _user, null, null, null);

            _eventFactory.Timestamp = 1000;
            Event event2 = _eventFactory.NewFeatureRequestEvent(flag, _user, null, null, null);

            _eventFactory.Timestamp = 1500;
            Event event3 = _eventFactory.NewFeatureRequestEvent(flag, _user, null, null, null);

            es.SummarizeEvent(event1);
            es.SummarizeEvent(event2);
            es.SummarizeEvent(event3);
            EventSummary data = es.Snapshot();

            Assert.Equal(1000, data.StartDate);
            Assert.Equal(2000, data.EndDate);
        }
        public void TwoFeatureEventsForSameUserGenerateOnlyOneIndexEvent()
        {
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag1 = new FlagEventPropertiesBuilder("flagkey1").Version(11).TrackEvents(true).Build();
            IFlagEventProperties flag2 = new FlagEventPropertiesBuilder("flagkey2").Version(22).TrackEvents(true).Build();
            var value = LdValue.Of("value");
            FeatureRequestEvent fe1 = EventFactory.Default.NewFeatureRequestEvent(flag1, _user,
                                                                                  new EvaluationDetail <LdValue>(value, 1, null), LdValue.Null);
            FeatureRequestEvent fe2 = EventFactory.Default.NewFeatureRequestEvent(flag2, _user,
                                                                                  new EvaluationDetail <LdValue>(value, 1, null), LdValue.Null);

            _ep.SendEvent(fe1);
            _ep.SendEvent(fe2);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckIndexEvent(item, fe1, _userJson),
                              item => CheckFeatureEvent(item, fe1, flag1, false, null),
                              item => CheckFeatureEvent(item, fe2, flag2, false, null),
                              item => CheckSummaryEvent(item));
        }
        public void NonTrackedEventsAreSummarized()
        {
            _ep = MakeProcessor(_config);
            IFlagEventProperties flag1 = new FlagEventPropertiesBuilder("flagkey1").Version(11).Build();
            IFlagEventProperties flag2 = new FlagEventPropertiesBuilder("flagkey2").Version(22).Build();
            JValue value            = new JValue("value");
            JValue default1         = new JValue("default1");
            JValue default2         = new JValue("default2");
            FeatureRequestEvent fe1 = EventFactory.Default.NewFeatureRequestEvent(flag1, _user,
                                                                                  1, value, default1);
            FeatureRequestEvent fe2 = EventFactory.Default.NewFeatureRequestEvent(flag2, _user,
                                                                                  1, value, default2);

            _ep.SendEvent(fe1);
            _ep.SendEvent(fe2);

            JArray output = FlushAndGetEvents(OkResponse());

            Assert.Collection(output,
                              item => CheckIndexEvent(item, fe1, _userJson),
                              item => CheckSummaryEventCounters(item, fe1, fe2));
        }
        public void SummarizeEventIncrementsCounters()
        {
            EventSummarizer      es    = new EventSummarizer();
            IFlagEventProperties flag1 = new FlagEventPropertiesBuilder("key1").Build();
            IFlagEventProperties flag2 = new FlagEventPropertiesBuilder("key2").Build();
            string unknownFlagKey      = "badkey";
            var    default1            = LdValue.Of("default1");
            var    default2            = LdValue.Of("default2");
            var    default3            = LdValue.Of("default3");
            Event  event1 = _eventFactory.NewFeatureRequestEvent(flag1, _user,
                                                                 new EvaluationDetail <LdValue>(LdValue.Of("value1"), 1, null), default1);
            Event event2 = _eventFactory.NewFeatureRequestEvent(flag1, _user,
                                                                new EvaluationDetail <LdValue>(LdValue.Of("value2"), 2, null), default1);
            Event event3 = _eventFactory.NewFeatureRequestEvent(flag2, _user,
                                                                new EvaluationDetail <LdValue>(LdValue.Of("value99"), 1, null), default2);
            Event event4 = _eventFactory.NewFeatureRequestEvent(flag1, _user,
                                                                new EvaluationDetail <LdValue>(LdValue.Of("value1"), 1, null), default1);
            Event event5 = _eventFactory.NewUnknownFeatureRequestEvent(unknownFlagKey, _user, default3, EvaluationErrorKind.FLAG_NOT_FOUND);

            es.SummarizeEvent(event1);
            es.SummarizeEvent(event2);
            es.SummarizeEvent(event3);
            es.SummarizeEvent(event4);
            es.SummarizeEvent(event5);
            EventSummary data = es.Snapshot();

            Dictionary <EventsCounterKey, EventsCounterValue> expected = new Dictionary <EventsCounterKey, EventsCounterValue>();

            Assert.Equal(new EventsCounterValue(2, LdValue.Of("value1"), default1),
                         data.Counters[new EventsCounterKey(flag1.Key, flag1.EventVersion, 1)]);
            Assert.Equal(new EventsCounterValue(1, LdValue.Of("value2"), default1),
                         data.Counters[new EventsCounterKey(flag1.Key, flag1.EventVersion, 2)]);
            Assert.Equal(new EventsCounterValue(1, LdValue.Of("value99"), default2),
                         data.Counters[new EventsCounterKey(flag2.Key, flag2.EventVersion, 1)]);
            Assert.Equal(new EventsCounterValue(1, default3, default3),
                         data.Counters[new EventsCounterKey(unknownFlagKey, null, null)]);
        }
        public void FeatureEventIsSerialized()
        {
            var factory           = new EventFactory(() => 100000, false);
            var factoryWithReason = new EventFactory(() => 100000, true);
            var flag = new FlagEventPropertiesBuilder("flag")
                       .Version(11)
                       .Build();
            var user = User.Builder("userkey").Name("me").Build();

            var feWithVariation = factory.NewFeatureRequestEvent(flag, user,
                                                                 new EvaluationDetail <LdValue>(LdValue.Of("flagvalue"), 1, EvaluationReason.OffReason),
                                                                 LdValue.Of("defaultvalue"));
            var feJson1 = LdValue.Parse(@"{
                ""kind"":""feature"",
                ""creationDate"":100000,
                ""key"":""flag"",
                ""version"":11,
                ""userKey"":""userkey"",
                ""value"":""flagvalue"",
                ""variation"":1,
                ""default"":""defaultvalue""
                }");

            TestEventSerialization(feWithVariation, feJson1);

            var feWithoutVariationOrDefault = factory.NewFeatureRequestEvent(flag, user,
                                                                             new EvaluationDetail <LdValue>(LdValue.Of("flagvalue"), null, EvaluationReason.OffReason),
                                                                             LdValue.Null);
            var feJson2 = LdValue.Parse(@"{
                ""kind"":""feature"",
                ""creationDate"":100000,
                ""key"":""flag"",
                ""version"":11,
                ""userKey"":""userkey"",
                ""value"":""flagvalue""
                }");

            TestEventSerialization(feWithoutVariationOrDefault, feJson2);

            var feWithReason = factoryWithReason.NewFeatureRequestEvent(flag, user,
                                                                        new EvaluationDetail <LdValue>(LdValue.Of("flagvalue"), 1, EvaluationReason.RuleMatchReason(1, "id")),
                                                                        LdValue.Of("defaultvalue"));
            var feJson3 = LdValue.Parse(@"{
                ""kind"":""feature"",
                ""creationDate"":100000,
                ""key"":""flag"",
                ""version"":11,
                ""userKey"":""userkey"",
                ""value"":""flagvalue"",
                ""variation"":1,
                ""default"":""defaultvalue"",
                ""reason"":{""kind"":""RULE_MATCH"",""ruleIndex"":1,""ruleId"":""id""}
                }");

            TestEventSerialization(feWithReason, feJson3);

            var feUnknownFlag = factoryWithReason.NewUnknownFeatureRequestEvent("flag", user,
                                                                                LdValue.Of("defaultvalue"), EvaluationErrorKind.FLAG_NOT_FOUND);
            var feJson4 = LdValue.Parse(@"{
                ""kind"":""feature"",
                ""creationDate"":100000,
                ""key"":""flag"",
                ""userKey"":""userkey"",
                ""value"":""defaultvalue"",
                ""default"":""defaultvalue"",
                ""reason"":{""kind"":""FLAG_NOT_FOUND""}
                }");

            TestEventSerialization(feWithReason, feJson3);

            var debugEvent = factory.NewDebugEvent(feWithVariation);
            var feJson5    = LdValue.Parse(@"{
                ""kind"":""debug"",
                ""creationDate"":100000,
                ""key"":""flag"",
                ""version"":11,
                ""user"":{""key"":""userkey"",""name"":""me""},
                ""value"":""flagvalue"",
                ""variation"":1,
                ""default"":""defaultvalue""
                }");

            TestEventSerialization(debugEvent, feJson5);
        }