コード例 #1
0
        internal async Task ExecuteAsync_WhenHttpExceptionOccurs_CompletesSuccessfully(
            HttpStatusCode statusCode,
            string responseBody,
            string responseContentType,
            [Frozen] UnleashSettings settings,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            List <string> strategies)
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            var backgroundTask = new ClientRegistrationBackgroundTask(apiClientFactoryMock.Object, settings, strategies);

            httpMessageHandler.SetupPostRegisterClientRequestForException(requestHeaders, statusCode, responseBody, responseContentType);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient);

            await backgroundTask.ExecuteAsync(CancellationToken.None);

            httpMessageHandler.VerifyAll();
            apiClientFactoryMock.VerifyAll();
        }
コード例 #2
0
        internal async Task FetchToggles_WhenServerReturns304NotModified_ReturnsCacheHitResult(
            UnleashSettings settings,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            string etagMinusQuotes
            )
        {
            var etag = $"\"{etagMinusQuotes}\"";

            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            httpMessageHandler.SetupGetFeaturesRequestForCacheHit(requestHeaders, etag);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None);

            Assert.Null(actualFetchTogglesResult.ToggleCollection);
            Assert.False(actualFetchTogglesResult.HasChanged);
            Assert.Equal(etag, actualFetchTogglesResult.Etag);

            httpMessageHandler.VerifyAll();
        }
コード例 #3
0
        internal async Task FetchToggles_WhenHttpExceptionOccurs_ReturnsEmptyResult(
            HttpStatusCode responseStatusCode,
            string responseBody,
            string responseContentType,
            UnleashSettings settings,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            string etag
            )
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            httpMessageHandler.SetupGetFeaturesRequestForException(requestHeaders, responseStatusCode, responseBody, responseContentType);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None);

            Assert.Null(actualFetchTogglesResult.ToggleCollection);
            Assert.Null(actualFetchTogglesResult.Etag);
            Assert.False(actualFetchTogglesResult.HasChanged);

            httpMessageHandler.VerifyAll();
        }
コード例 #4
0
        internal async Task FetchToggles_WhenServerReturnsExpectedToggles_ReturnsValidResult(
            UnleashSettings settings,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            string etag
            )
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            var expectedToggles = new ToggleCollection();

            httpMessageHandler.SetupGetFeaturesRequestForSuccess(jsonSerializer, expectedToggles, requestHeaders);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None);

            var actualToggles = actualFetchTogglesResult.ToggleCollection;

            Assert.Equal(expectedToggles.Features, actualToggles.Features);
            Assert.True(actualFetchTogglesResult.HasChanged);
            Assert.NotEqual(etag, actualFetchTogglesResult.Etag);

            httpMessageHandler.VerifyAll();
        }
コード例 #5
0
        internal async Task RegisterMetrics_WhenHttpExceptionOccurs_ReturnsFalse(
            HttpStatusCode responseStatusCode,
            string responseBody,
            string responseContentType,
            UnleashSettings settings,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            MetricsBucket metricsBucket
            )
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            httpMessageHandler.SetupPostSendMetricsRequestForException(requestHeaders, responseStatusCode, responseBody, responseContentType);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket);
            var successResult           = await apiClient.SendMetrics(threadSafeMetricsBucket, CancellationToken.None);

            Assert.False(successResult);

            httpMessageHandler.VerifyAll();
        }
コード例 #6
0
        internal async Task RegisterMetrics_WhenServerReturns200Ok_ReturnsTrue(
            UnleashSettings settings,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            MetricsBucket metricsBucket
            )
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            httpMessageHandler.SetupPostSendMetricsRequestForSuccess(requestHeaders);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket);
            var successResult           = await apiClient.SendMetrics(threadSafeMetricsBucket, CancellationToken.None);

            Assert.True(successResult);

            httpMessageHandler.VerifyAll();
        }
コード例 #7
0
        internal async Task ExecuteAsync_WhenApiReturns200Ok_CompletesSuccessfully(
            [Frozen] UnleashSettings settings,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            [Frozen] MetricsBucket metricsBucket)
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket);
            var backgroundTask          = new ClientMetricsBackgroundTask(apiClientFactoryMock.Object, settings, threadSafeMetricsBucket);

            httpMessageHandler.SetupPostSendMetricsRequestForSuccess(requestHeaders);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient);

            await backgroundTask.ExecuteAsync(CancellationToken.None);

            httpMessageHandler.VerifyAll();
            apiClientFactoryMock.VerifyAll();
        }
コード例 #8
0
        private static IUnleashApiClient CreateApiClient()
        {
            var apiUri = new Uri("http://unleash.herokuapp.com/api/");

            var jsonSerializer = new DynamicNewtonsoftJsonSerializer();

            jsonSerializer.TryLoad();

            var httpClientFactory = new DefaultHttpClientFactory();

            var requestHeaders = new UnleashApiClientRequestHeaders
            {
                AppName           = "api-test-client",
                InstanceTag       = "instance1",
                CustomHttpHeaders = new Dictionary <string, string>()
                {
                    // "Test" token from 21.10.2021
                    { "Authorization", "*:default.77c45b703a681983b714fee87e575a823bfb1fd0ab282d9399647243" }
                },
                CustomHttpHeaderProvider = null
            };

            var httpClient = httpClientFactory.Create(apiUri);
            var client     = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            return(client);
        }
コード例 #9
0
        internal async Task ExecuteAsync_WhenHttpExceptionOccurs_CompletesSuccessfully(
            HttpStatusCode statusCode,
            string responseBody,
            string responseContentType,
            [Frozen] UnleashSettings settings,
            [Frozen] ThreadSafeToggleCollection toggleCollection,
            [Frozen] Mock <IToggleCollectionCache> toggleCollectionCache,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            TaskCompletionSource <object> taskCompletionSource)
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            var backgroundTask = new FetchFeatureTogglesTask(apiClientFactoryMock.Object, toggleCollection, toggleCollectionCache.Object, taskCompletionSource);

            httpMessageHandler.SetupGetFeaturesRequestForException(requestHeaders, statusCode, responseBody, responseContentType);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient);

            await backgroundTask.ExecuteAsync(CancellationToken.None);

            Assert.True(taskCompletionSource.Task.IsCompletedSuccessfully);

            httpMessageHandler.VerifyAll();
            apiClientFactoryMock.VerifyAll();
            toggleCollectionCache.VerifyNoOtherCalls();
        }
コード例 #10
0
        internal async Task ExecuteAsync_WhenApiReturns200Ok_CompletesSuccessfully(
            [Frozen] UnleashSettings settings,
            [Frozen] ThreadSafeToggleCollection toggleCollection,
            [Frozen] Mock <IToggleCollectionCache> toggleCollectionCache,
            [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler,
            [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock,
            [Frozen] UnleashApiClientRequestHeaders requestHeaders,
            TaskCompletionSource <object> taskCompletionSource)
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            var toggleCollectionInstance = toggleCollection.Instance;

            toggleCollectionCache
            .Setup(
                x => x.Save(
                    It.Is <ToggleCollection>(
                        y => y.Version.Equals(toggleCollectionInstance.Version) &&
                        y.Features.All(
                            z => toggleCollectionInstance.Features.Any(zz => zz.Name.Equals(z.Name))
                            )
                        ),
                    It.IsAny <string>(),
                    CancellationToken.None
                    )
                )
            .Returns(Task.CompletedTask);

            var backgroundTask = new FetchFeatureTogglesTask(apiClientFactoryMock.Object, toggleCollection, toggleCollectionCache.Object, taskCompletionSource);

            httpMessageHandler.SetupGetFeaturesRequestForSuccess(jsonSerializer, toggleCollectionInstance, requestHeaders);

            var httpClient = new HttpClient(httpMessageHandler.Object)
            {
                BaseAddress = settings.UnleashApi
            };
            var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient);

            await backgroundTask.ExecuteAsync(CancellationToken.None);

            Assert.True(taskCompletionSource.Task.IsCompletedSuccessfully);

            httpMessageHandler.VerifyAll();
            apiClientFactoryMock.VerifyAll();
            toggleCollectionCache.VerifyAll();
        }
コード例 #11
0
        protected BaseUnleashApiClientIntegrationTests()
        {
            var apiUri = new Uri("http://localhost:4242/");

            var jsonSerializer = new NewtonsoftJsonSerializer(new NewtonsoftJsonSerializerSettings());

            var httpClientFactory = new DefaultHttpClientFactory();

            var requestHeaders = new UnleashApiClientRequestHeaders
            {
                AppName           = "api-test-client",
                InstanceTag       = "instance1",
                CustomHttpHeaders = null
            };

            var httpClient = httpClientFactory.Create(apiUri);

            Client      = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);
            AdminClient = new UnleashAdminApiClient(httpClient, jsonSerializer);
        }
コード例 #12
0
        private static IUnleashApiClient CreateApiClient()
        {
            var apiUri = new Uri("http://unleash.herokuapp.com/api/");

            var jsonSerializer = new DynamicNewtonsoftJsonSerializer();

            jsonSerializer.TryLoad();

            var httpClientFactory = new DefaultHttpClientFactory();

            var requestHeaders = new UnleashApiClientRequestHeaders
            {
                AppName           = "api-test-client",
                InstanceTag       = "instance1",
                CustomHttpHeaders = null
            };

            var httpClient = httpClientFactory.Create(apiUri);
            var client     = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            return(client);
        }
コード例 #13
0
        private IUnleashApiClient CreateApiClient()
        {
            var jsonSerializer = new DynamicNewtonsoftJsonSerializer();

            jsonSerializer.TryLoad();

            var requestHeaders = new UnleashApiClientRequestHeaders
            {
                AppName                  = "api-test-client",
                InstanceTag              = "instance1",
                CustomHttpHeaders        = httpHeaders,
                CustomHttpHeaderProvider = httpHeadersProvider
            };

            var httpClient = new HttpClient(messageHandler)
            {
                BaseAddress = new Uri("http://example.com")
            };
            var client = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders);

            return(client);
        }
コード例 #14
0
        public UnleashServices(UnleashSettings settings, Dictionary <string, IStrategy> strategyMap)
        {
            var fileSystem = settings.FileSystem ?? new FileSystem(settings.Encoding);

            var backupFile     = settings.GetFeatureToggleFilePath();
            var etagBackupFile = settings.GetFeatureToggleETagFilePath();

            // Cancellation
            CancellationToken = cancellationTokenSource.Token;
            ContextProvider   = settings.UnleashContextProvider;


            var loader            = new CachedFilesLoader(settings.JsonSerializer, fileSystem, backupFile, etagBackupFile);
            var cachedFilesResult = loader.EnsureExistsAndLoad();

            ToggleCollection = new ThreadSafeToggleCollection
            {
                Instance = cachedFilesResult.InitialToggleCollection ?? new ToggleCollection()
            };

            MetricsBucket = new ThreadSafeMetricsBucket();

            IUnleashApiClient apiClient;

            if (settings.UnleashApiClient == null)
            {
                var httpClient = settings.HttpClientFactory.Create(settings.UnleashApi);
                apiClient = new UnleashApiClient(httpClient, settings.JsonSerializer, new UnleashApiClientRequestHeaders()
                {
                    AppName           = settings.AppName,
                    InstanceTag       = settings.InstanceTag,
                    CustomHttpHeaders = settings.CustomHttpHeaders
                });
                if (settings.LoadTogglesImmediately)
                {
                    var toggles = apiClient.FetchToggles("", CancellationToken.None);
                    ToggleCollection.Instance = toggles.Result.ToggleCollection;
                }
            }
            else
            {
                // Mocked backend: fill instance collection
                apiClient = settings.UnleashApiClient;
                var toggles = apiClient.FetchToggles("", CancellationToken.None);
                ToggleCollection.Instance = toggles.Result.ToggleCollection;
            }

            scheduledTaskManager = settings.ScheduledTaskManager;

            IsMetricsDisabled = settings.SendMetricsInterval == null;

            var fetchFeatureTogglesTask = new FetchFeatureTogglesTask(
                apiClient,
                ToggleCollection,
                settings.JsonSerializer,
                fileSystem,
                backupFile,
                etagBackupFile)
            {
                ExecuteDuringStartup = true,
                Interval             = settings.FetchTogglesInterval,
                Etag = cachedFilesResult.InitialETag
            };

            var scheduledTasks = new List <IUnleashScheduledTask>()
            {
                fetchFeatureTogglesTask
            };

            if (settings.SendMetricsInterval != null)
            {
                var clientRegistrationBackgroundTask = new ClientRegistrationBackgroundTask(
                    apiClient,
                    settings,
                    strategyMap.Select(pair => pair.Key).ToList())
                {
                    Interval             = TimeSpan.Zero,
                    ExecuteDuringStartup = true
                };

                scheduledTasks.Add(clientRegistrationBackgroundTask);

                var clientMetricsBackgroundTask = new ClientMetricsBackgroundTask(
                    apiClient,
                    settings,
                    MetricsBucket)
                {
                    ExecuteDuringStartup = false,
                    Interval             = settings.SendMetricsInterval.Value
                };

                scheduledTasks.Add(clientMetricsBackgroundTask);
            }

            scheduledTaskManager.Configure(scheduledTasks, CancellationToken);
        }