コード例 #1
0
        public void VariationSendsFeatureEventForUnknownFlagWhenClientIsNotInitialized()
        {
            var config = BasicConfig()
                         .DataSource(new MockDataSourceThatNeverInitializes().AsSingletonFactory())
                         .Events(_factory);

            using (LdClient client = TestUtil.CreateClient(config.Build(), user))
            {
                string result = client.StringVariation("flag", "b");
                Assert.Equal("b", result);
                Assert.Collection(eventProcessor.Events,
                                  e => CheckIdentifyEvent(e, user),
                                  e =>
                {
                    EvaluationEvent fe = Assert.IsType <EvaluationEvent>(e);
                    Assert.Equal("flag", fe.FlagKey);
                    Assert.Equal("b", fe.Value.AsString);
                    Assert.Null(fe.Variation);
                    Assert.Null(fe.FlagVersion);
                    Assert.Equal("b", fe.Default.AsString);
                    Assert.Null(fe.Reason);
                    Assert.NotEqual(0, fe.Timestamp.Value);
                });
            }
        }
コード例 #2
0
        public void VariationSendsFeatureEventWithReasonForUnknownFlagWhenClientIsNotInitialized()
        {
            var config = BasicConfig()
                         .DataSource(new MockDataSourceThatNeverInitializes().AsSingletonFactory())
                         .Events(_factory);

            using (LdClient client = TestUtil.CreateClient(config.Build(), user))
            {
                EvaluationDetail <string> result = client.StringVariationDetail("flag", "b");
                var expectedReason = EvaluationReason.ErrorReason(EvaluationErrorKind.ClientNotReady);
                Assert.Equal("b", result.Value);
                Assert.Equal(expectedReason, result.Reason);
                Assert.Collection(eventProcessor.Events,
                                  e => CheckIdentifyEvent(e, user),
                                  e => {
                    EvaluationEvent fe = Assert.IsType <EvaluationEvent>(e);
                    Assert.Equal("flag", fe.FlagKey);
                    Assert.Equal("b", fe.Value.AsString);
                    Assert.Null(fe.Variation);
                    Assert.Null(fe.FlagVersion);
                    Assert.Equal("b", fe.Default.AsString);
                    Assert.False(fe.TrackEvents);
                    Assert.Null(fe.DebugEventsUntilDate);
                    Assert.Equal(expectedReason, fe.Reason);
                    Assert.NotEqual(0, fe.Timestamp.Value);
                });
            }
        }
コード例 #3
0
        public void CanCreateClientWithInfiniteWaitTime()
        {
            var config = BasicConfig().Build();

            using (var client = LdClient.Init(config, BasicUser, System.Threading.Timeout.InfiniteTimeSpan)) { }
            TestUtil.ClearClient();
        }
コード例 #4
0
        public void VariationDetailSendsFeatureEventWithReasonForValidFlag()
        {
            var flag = new FeatureFlagBuilder().Value(LdValue.Of("a")).Variation(1).Version(1000)
                       .TrackEvents(true).DebugEventsUntilDate(UnixMillisecondTime.OfMillis(2000))
                       .Reason(EvaluationReason.OffReason).Build();

            _testData.Update(_testData.Flag("flag").PreconfiguredFlag(flag));
            using (LdClient client = MakeClient(user))
            {
                EvaluationDetail <string> result = client.StringVariationDetail("flag", "b");
                Assert.Equal("a", result.Value);
                Assert.Equal(EvaluationReason.OffReason, result.Reason);
                Assert.Collection(eventProcessor.Events,
                                  e => CheckIdentifyEvent(e, user),
                                  e => {
                    EvaluationEvent fe = Assert.IsType <EvaluationEvent>(e);
                    Assert.Equal("flag", fe.FlagKey);
                    Assert.Equal("a", fe.Value.AsString);
                    Assert.Equal(1, fe.Variation);
                    Assert.Equal(1000, fe.FlagVersion);
                    Assert.Equal("b", fe.Default.AsString);
                    Assert.True(fe.TrackEvents);
                    Assert.Equal(UnixMillisecondTime.OfMillis(2000), fe.DebugEventsUntilDate);
                    Assert.Equal(EvaluationReason.OffReason, fe.Reason);
                    Assert.NotEqual(0, fe.Timestamp.Value);
                });
            }
        }
コード例 #5
0
        private async Task IdentifyCompletesOnlyWhenNewFlagsAreAvailable(Func <LdClient, User, Task> identifyTask)
        {
            var userA = User.WithKey("a");
            var userB = User.WithKey("b");

            var flagKey    = "flag";
            var userAFlags = new DataSetBuilder()
                             .Add(flagKey, 1, LdValue.Of("a-value"), 0).Build();
            var userBFlags = new DataSetBuilder()
                             .Add(flagKey, 2, LdValue.Of("b-value"), 1).Build();

            var startedIdentifyUserB   = new SemaphoreSlim(0, 1);
            var canFinishIdentifyUserB = new SemaphoreSlim(0, 1);
            var finishedIdentifyUserB  = new SemaphoreSlim(0, 1);

            var dataSourceFactory = new MockDataSourceFactoryFromLambda((ctx, updates, user, bg) =>
                                                                        new MockDataSourceFromLambda(user, async() =>
            {
                switch (user.Key)
                {
                case "a":
                    updates.Init(user, userAFlags);
                    break;

                case "b":
                    startedIdentifyUserB.Release();
                    await canFinishIdentifyUserB.WaitAsync();
                    updates.Init(user, userBFlags);
                    break;
                }
            }));

            var config = BasicConfig()
                         .DataSource(dataSourceFactory)
                         .Build();

            using (var client = await LdClient.InitAsync(config, userA))
            {
                Assert.True(client.Initialized);
                Assert.Equal("a-value", client.StringVariation(flagKey, null));

                var identifyUserBTask = Task.Run(async() =>
                {
                    await identifyTask(client, userB);
                    finishedIdentifyUserB.Release();
                });

                await startedIdentifyUserB.WaitAsync();

                Assert.False(client.Initialized);
                Assert.Null(client.StringVariation(flagKey, null));

                canFinishIdentifyUserB.Release();
                await finishedIdentifyUserB.WaitAsync();

                Assert.True(client.Initialized);
                Assert.Equal("b-value", client.StringVariation(flagKey, null));
            }
        }
コード例 #6
0
 // Calls LdClient.Init, but then sets LdClient.Instance to null so other tests can
 // instantiate their own independent clients. Application code cannot do this because
 // the LdClient.Instance setter has internal scope.
 public static async Task <LdClient> CreateClientAsync(Configuration config, User user)
 {
     return(await WithClientLockAsync(async() =>
     {
         ClearClient();
         LdClient client = await LdClient.InitAsync(config, user);
         client.DetachInstance();
         return client;
     }));
 }
コード例 #7
0
 // Calls LdClient.Init, but then sets LdClient.Instance to null so other tests can
 // instantiate their own independent clients. Application code cannot do this because
 // the LdClient.Instance setter has internal scope.
 public static LdClient CreateClient(Configuration config, User user, TimeSpan?timeout = null)
 {
     return(WithClientLock(() =>
     {
         ClearClient();
         LdClient client = LdClient.Init(config, user, timeout ?? TimeSpan.FromSeconds(1));
         client.DetachInstance();
         return client;
     }));
 }
コード例 #8
0
 public void IdentifySendsIdentifyEvent()
 {
     using (LdClient client = MakeClient(user))
     {
         User user1 = User.WithKey("userkey1");
         client.Identify(user1, TimeSpan.FromSeconds(1));
         Assert.Collection(eventProcessor.Events,
                           e => CheckIdentifyEvent(e, user), // there's always an initial identify event
                           e => CheckIdentifyEvent(e, user1));
     }
 }
コード例 #9
0
 public void SharedClientIsTheOnlyClientAvailable()
 {
     TestUtil.WithClientLock(() =>
     {
         var config = BasicConfig().Build();
         using (var client = LdClient.Init(config, BasicUser, TimeSpan.Zero))
         {
             Assert.Throws <Exception>(() => LdClient.Init(config, BasicUser, TimeSpan.Zero));
         }
         TestUtil.ClearClient();
     });
 }
コード例 #10
0
 public void CanCreateNewClientAfterDisposingOfSharedInstance()
 {
     TestUtil.WithClientLock(() =>
     {
         TestUtil.ClearClient();
         var config = BasicConfig().Build();
         using (var client0 = LdClient.Init(config, BasicUser, TimeSpan.Zero)) { }
         Assert.Null(LdClient.Instance);
         // Dispose() is called automatically at end of "using" block
         using (var client1 = LdClient.Init(config, BasicUser, TimeSpan.Zero)) { }
     });
 }
コード例 #11
0
        static LdClient CreateInstance(Configuration configuration, User user, TimeSpan maxWaitTime)
        {
            lock (_createInstanceLock)
            {
                if (_instance != null)
                {
                    throw new Exception("LdClient instance already exists.");
                }

                var c = new LdClient(configuration, user, maxWaitTime);
                _instance = c;
                return(c);
            }
        }
コード例 #12
0
        public async void InitPassesUserToDataSource()
        {
            MockPollingProcessor stub = new MockPollingProcessor(DataSetBuilder.Empty);

            var config = BasicConfig()
                         .DataSource(stub.AsFactory())
                         .Build();

            using (var client = await LdClient.InitAsync(config, BasicUser))
            {
                var actualUser = client.User; // may have been transformed e.g. to add device/OS properties
                Assert.Equal(BasicUser.Key, actualUser.Key);
                Assert.Equal(actualUser, stub.ReceivedUser);
            }
        }
コード例 #13
0
        public void IdentifyDoesNotSendAliasEventIfNewUserIsAnonymousOrOldUserIsNot(
            bool oldAnon, bool newAnon)
        {
            User oldUser = User.Builder("old-key").Anonymous(oldAnon).Build();
            User newUser = User.Builder("new-key").Anonymous(newAnon).Build();

            using (LdClient client = MakeClient(oldUser))
            {
                client.Identify(newUser, TimeSpan.FromSeconds(1));

                Assert.Collection(eventProcessor.Events,
                                  e => CheckIdentifyEvent(e, oldUser),
                                  e => CheckIdentifyEvent(e, newUser));
            }
        }
コード例 #14
0
        public async void InitWithKeylessAnonUserPassesGeneratedUserToDataSource()
        {
            MockPollingProcessor stub = new MockPollingProcessor(DataSetBuilder.Empty);

            var config = BasicConfig()
                         .DataSource(stub.AsFactory())
                         .Build();

            using (var client = await LdClient.InitAsync(config, KeylessAnonUser))
            {
                AssertHelpers.UsersEqualExcludingAutoProperties(
                    User.Builder(KeylessAnonUser).Key(stub.ReceivedUser.Key).Build(),
                    stub.ReceivedUser);
            }
        }
コード例 #15
0
 public void TrackSendsCustomEvent()
 {
     using (LdClient client = MakeClient(user))
     {
         client.Track("eventkey");
         Assert.Collection(eventProcessor.Events,
                           e => CheckIdentifyEvent(e, user),
                           e => {
             CustomEvent ce = Assert.IsType <CustomEvent>(e);
             Assert.Equal("eventkey", ce.EventKey);
             Assert.Equal(user.Key, ce.User.Key);
             Assert.Equal(LdValue.Null, ce.Data);
             Assert.Null(ce.MetricValue);
             Assert.NotEqual(0, ce.Timestamp.Value);
         });
     }
 }
コード例 #16
0
        public void AliasSendsAliasEvent()
        {
            User oldUser = User.Builder("anon-key").Anonymous(true).Build();
            User newUser = User.WithKey("real-key");

            using (LdClient client = MakeClient(user))
            {
                client.Alias(user, oldUser);
                Assert.Collection(eventProcessor.Events,
                                  e => CheckIdentifyEvent(e, user),
                                  e => {
                    AliasEvent ae = Assert.IsType <AliasEvent>(e);
                    Assert.Equal(user, ae.User);
                    Assert.Equal(oldUser, ae.PreviousUser);
                    Assert.NotEqual(0, ae.Timestamp.Value);
                });
            }
        }
コード例 #17
0
 public void TrackWithMetricValueSendsCustomEvent()
 {
     using (LdClient client = MakeClient(user))
     {
         LdValue data        = LdValue.Of("hi");
         double  metricValue = 1.5;
         client.Track("eventkey", data, metricValue);
         Assert.Collection(eventProcessor.Events,
                           e => CheckIdentifyEvent(e, user),
                           e => {
             CustomEvent ce = Assert.IsType <CustomEvent>(e);
             Assert.Equal("eventkey", ce.EventKey);
             Assert.Equal(user.Key, ce.User.Key);
             Assert.Equal(data, ce.Data);
             Assert.Equal(metricValue, ce.MetricValue);
             Assert.NotEqual(0, ce.Timestamp.Value);
         });
     }
 }
コード例 #18
0
        public void IdentifyDoesNotSendAliasEventIfOptedOUt()
        {
            User oldUser = User.Builder("anon-key").Anonymous(true).Build();
            User newUser = User.WithKey("real-key");

            var config = BasicConfig()
                         .Events(_factory)
                         .AutoAliasingOptOut(true)
                         .Build();

            using (LdClient client = TestUtil.CreateClient(config, oldUser))
            {
                User actualOldUser = client.User; // so we can get any automatic properties that the client added
                client.Identify(newUser, TimeSpan.FromSeconds(1));

                Assert.Collection(eventProcessor.Events,
                                  e => CheckIdentifyEvent(e, actualOldUser),
                                  e => CheckIdentifyEvent(e, newUser));
            }
        }
コード例 #19
0
        public async void IdentifyPassesUserToDataSource()
        {
            MockPollingProcessor stub = new MockPollingProcessor(DataSetBuilder.Empty);
            User newUser = User.WithKey("new-user");

            var config = BasicConfig()
                         .DataSource(stub.AsFactory())
                         .Build();

            using (var client = await LdClient.InitAsync(config, BasicUser))
            {
                AssertHelpers.UsersEqualExcludingAutoProperties(BasicUser, client.User);
                Assert.Equal(client.User, stub.ReceivedUser);

                await client.IdentifyAsync(newUser);

                AssertHelpers.UsersEqualExcludingAutoProperties(newUser, client.User);
                Assert.Equal(client.User, stub.ReceivedUser);
            }
        }
コード例 #20
0
 public void VariationSendsFeatureEventForUnknownFlag()
 {
     using (LdClient client = MakeClient(user))
     {
         string result = client.StringVariation("flag", "b");
         Assert.Equal("b", result);
         Assert.Collection(eventProcessor.Events,
                           e => CheckIdentifyEvent(e, user),
                           e => {
             EvaluationEvent fe = Assert.IsType <EvaluationEvent>(e);
             Assert.Equal("flag", fe.FlagKey);
             Assert.Equal("b", fe.Value.AsString);
             Assert.Null(fe.Variation);
             Assert.Null(fe.FlagVersion);
             Assert.Equal("b", fe.Default.AsString);
             Assert.Null(fe.Reason);
             Assert.NotEqual(0, fe.Timestamp.Value);
         });
     }
 }
コード例 #21
0
        public void IdentifySendsAliasEventFromAnonUserToNonAnonUserIfNotOptedOut()
        {
            User oldUser = User.Builder("anon-key").Anonymous(true).Build();
            User newUser = User.WithKey("real-key");

            using (LdClient client = MakeClient(oldUser))
            {
                User actualOldUser = client.User; // so we can get any automatic properties that the client added
                client.Identify(newUser, TimeSpan.FromSeconds(1));

                Assert.Collection(eventProcessor.Events,
                                  e => CheckIdentifyEvent(e, actualOldUser),
                                  e => CheckIdentifyEvent(e, newUser),
                                  e => {
                    AliasEvent ae = Assert.IsType <AliasEvent>(e);
                    Assert.Equal(newUser, ae.User);
                    Assert.Equal(actualOldUser, ae.PreviousUser);
                    Assert.NotEqual(0, ae.Timestamp.Value);
                });
            }
        }
コード例 #22
0
        public void VariationSendsFeatureEventForDefaultValue()
        {
            var flag = new FeatureFlagBuilder().Version(1000).Build();

            _testData.Update(_testData.Flag("flag").PreconfiguredFlag(flag));
            using (LdClient client = MakeClient(user))
            {
                string result = client.StringVariation("flag", "b");
                Assert.Equal("b", result);
                Assert.Collection(eventProcessor.Events,
                                  e => CheckIdentifyEvent(e, user),
                                  e => {
                    EvaluationEvent fe = Assert.IsType <EvaluationEvent>(e);
                    Assert.Equal("flag", fe.FlagKey);
                    Assert.Equal("b", fe.Value.AsString);
                    Assert.Null(fe.Variation);
                    Assert.Equal(1000, fe.FlagVersion);
                    Assert.Equal("b", fe.Default.AsString);
                    Assert.Null(fe.Reason);
                    Assert.NotEqual(0, fe.Timestamp.Value);
                });
            }
        }
コード例 #23
0
 public void VariationDetailSendsFeatureEventWithReasonForUnknownFlag()
 {
     using (LdClient client = MakeClient(user))
     {
         EvaluationDetail <string> result = client.StringVariationDetail("flag", "b");
         var expectedReason = EvaluationReason.ErrorReason(EvaluationErrorKind.FlagNotFound);
         Assert.Equal("b", result.Value);
         Assert.Equal(expectedReason, result.Reason);
         Assert.Collection(eventProcessor.Events,
                           e => CheckIdentifyEvent(e, user),
                           e => {
             EvaluationEvent fe = Assert.IsType <EvaluationEvent>(e);
             Assert.Equal("flag", fe.FlagKey);
             Assert.Equal("b", fe.Value.AsString);
             Assert.Null(fe.Variation);
             Assert.Null(fe.FlagVersion);
             Assert.Equal("b", fe.Default.AsString);
             Assert.False(fe.TrackEvents);
             Assert.Null(fe.DebugEventsUntilDate);
             Assert.Equal(expectedReason, fe.Reason);
             Assert.NotEqual(0, fe.Timestamp.Value);
         });
     }
 }
コード例 #24
0
 private LdClient MakeClient(User u) =>
 LdClient.Init(BasicConfig().DataSource(_testData).Events(_factory).Build(),
               u, TimeSpan.FromSeconds(1));
コード例 #25
0
        public void CannotCreateClientWithNegativeWaitTime()
        {
            var config = BasicConfig().Build();

            Assert.Throws <ArgumentOutOfRangeException>(() => LdClient.Init(config, BasicUser, TimeSpan.FromMilliseconds(-2)));
        }
コード例 #26
0
        public void CannotCreateClientWithNullUser()
        {
            var config = BasicConfig().Build();

            Assert.Throws <ArgumentNullException>(() => LdClient.Init(config, null, TimeSpan.Zero));
        }
コード例 #27
0
 public void CannotCreateClientWithNullConfig()
 {
     Assert.Throws <ArgumentNullException>(() => LdClient.Init((Configuration)null, BasicUser, TimeSpan.Zero));
 }