Пример #1
0
 internal static void SetupGetFeaturesRequestForCacheHit(this Mock <FakeHttpMessageHandler> mock,
                                                         UnleashApiClientRequestHeaders requestHeaders, string etag)
 {
     mock
     .Setup(mh => mh.Send(It.Is(ApiRequest(HttpMethod.Get, "api/client/features", requestHeaders))))
     .Returns(() => CacheHitResponse(etag));
 }
Пример #2
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();
        }
Пример #3
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();
        }
Пример #4
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();
        }
Пример #5
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();
        }
        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);
        }
Пример #7
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();
        }
Пример #8
0
 internal static void SetupPostSendMetricsRequestForException(this Mock <FakeHttpMessageHandler> mock,
                                                              UnleashApiClientRequestHeaders requestHeaders, HttpStatusCode statusCode, string responseBody = null, string responseContentType = null)
 {
     mock
     .Setup(mh => mh.Send(It.Is(ApiRequest(HttpMethod.Post, "api/client/metrics", requestHeaders))))
     .Returns(() => ExceptionResponse(statusCode, responseBody, responseContentType));
 }
Пример #9
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();
        }
Пример #10
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();
        }
Пример #11
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();
        }
Пример #12
0
 internal static void SetupGetFeaturesRequestForSuccess(this Mock <FakeHttpMessageHandler> mock,
                                                        IJsonSerializer jsonSerializer, ToggleCollection toggleCollectionResult,
                                                        UnleashApiClientRequestHeaders requestHeaders)
 {
     mock
     .Setup(mh => mh.Send(It.Is(ApiRequest(HttpMethod.Get, "api/client/features", requestHeaders))))
     .Returns(() => SerializedMessageResponse(jsonSerializer, toggleCollectionResult));
 }
        internal static IUnleashServiceCollection AddUnleash(this IServiceCollection serviceCollection, Action <UnleashSettings> settingsInitializer, IConfiguration configuration, Action <UnleashSettings> settingsOverrider)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

            var result = new UnleashServiceCollection(serviceCollection, configuration);

            var settings = new UnleashSettings();

            settingsInitializer?.Invoke(settings);
            configuration?.Bind(settings);
            settingsOverrider?.Invoke(settings);
            SettingsValidator.Validate(settings);

            var unleashApiClientRequestHeaders = new UnleashApiClientRequestHeaders
            {
                AppName           = settings.AppName,
                CustomHttpHeaders = settings.CustomHttpHeaders,
                InstanceTag       = settings.InstanceTag
            };

            serviceCollection.AddSingleton(settings);
            serviceCollection.AddSingleton <IRandom>(new UnleashRandom());
            serviceCollection.AddSingleton(serviceProvider => serviceProvider.GetService <IEnumerable <IStrategy> >()?.ToArray() ?? Array.Empty <IStrategy>());

            // Internal services
            serviceCollection.AddSingleton <NewtonsoftJsonSerializerSettings>();
            serviceCollection.AddSingleton <IJsonSerializer, NewtonsoftJsonSerializer>();
            serviceCollection.AddSingleton(unleashApiClientRequestHeaders);

            serviceCollection.AddSingleton <IHttpClientFactory, DefaultHttpClientFactory>();
            serviceCollection.AddSingleton <IUnleashApiClientFactory, DefaultUnleashApiClientFactory>();

            serviceCollection.AddSingleton <IUnleashApiClient, UnleashApiClient>();

            serviceCollection.AddSingleton <IUnleashServices, UnleashServices>();

            // Default: SystemTimer scheduled task manager
            serviceCollection.AddSingleton <IUnleashScheduledTaskManager, SystemTimerScheduledTaskManager>();

            // Default: Disk-based JSON toggle collection cache
            serviceCollection.AddSingleton <IFileSystem, FileSystem>();
            serviceCollection.AddSingleton <IToggleCollectionCache, FileSystemToggleCollectionCache>();

            serviceCollection.AddScoped <IUnleashContextProvider, DefaultUnleashContextProvider>();
            serviceCollection.AddScoped <IUnleash, Unleash>();

            return(result);
        }
Пример #14
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();
        }
Пример #15
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);
        }
Пример #16
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);
        }
        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);
        }
        private UnleashApiClient NewTestableClient(string project, MockHttpMessageHandler messageHandler)
        {
            var apiUri = new Uri("http://unleash.herokuapp.com/api/");

            var jsonSerializer = new DynamicNewtonsoftJsonSerializer();

            jsonSerializer.TryLoad();

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

            var httpClient = new HttpClient(messageHandler)
            {
                BaseAddress = apiUri,
                Timeout     = TimeSpan.FromSeconds(5)
            };

            return(new UnleashApiClient(httpClient, jsonSerializer, requestHeaders, project));
        }
Пример #19
0
 internal static void SetupPostSendMetricsRequestForSuccess(this Mock <FakeHttpMessageHandler> mock, UnleashApiClientRequestHeaders requestHeaders)
 {
     mock
     .Setup(mh => mh.Send(It.Is(ApiRequest(HttpMethod.Post, "api/client/metrics", requestHeaders))))
     .Returns(() => EmptyResponse(HttpStatusCode.OK));
 }