예제 #1
0
        public void TestAfterDisposeGetOptimizelyConfigIsNoLongerValid()
        {
            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithDatafile(TestData.Datafile)
                              .WithPollingInterval(TimeSpan.FromMilliseconds(50000))
                              .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(500))
                              .Build(true);
            var optimizely = new Optimizely(httpManager);

            httpManager.Start();

            var optimizelyConfig = optimizely.GetOptimizelyConfig();

            Assert.NotNull(optimizelyConfig);
            Assert.NotNull(optimizelyConfig.ExperimentsMap);
            Assert.NotNull(optimizelyConfig.FeaturesMap);
            Assert.NotNull(optimizelyConfig.Revision);

            optimizely.Dispose();

            var optimizelyConfigAfterDispose = optimizely.GetOptimizelyConfig();

            Assert.Null(optimizelyConfigAfterDispose);
        }
        public void TestHttpConfigManagerDoesNotWaitForTheConfigWhenDeferIsTrue()
        {
            var t = MockSendAsync(TestData.Datafile, TimeSpan.FromMilliseconds(150));

            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithLogger(LoggerMock.Object)
                              .WithPollingInterval(TimeSpan.FromSeconds(2))
                              // negligible timeout
                              .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(50))
                              .WithStartByDefault()
                              .Build(false);

            // When blocking timeout is 0 and defer is false and getconfig immediately called
            // should return null
            Assert.IsNull(httpManager.GetConfig());
            // wait until config is retrieved.
            t.Wait();
            // in case deadlock, it will release after 3sec.
            httpManager.OnReady().Wait(8000);

            HttpClientMock.Verify(_ => _.SendAsync(It.IsAny <HttpRequestMessage>()));
            Assert.NotNull(httpManager.GetConfig());

            httpManager.Dispose();
        }
예제 #3
0
        public void TestPollingGivenOnlySdkKeyGetOptimizelyConfig()
        {
            HttpProjectConfigManager httpManager = new HttpProjectConfigManager.Builder()
                                                   .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                                                   .WithLogger(LoggerMock.Object)
                                                   .WithPollingInterval(TimeSpan.FromMilliseconds(1000))
                                                   .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(500))
                                                   .WithStartByDefault()
                                                   .Build(true);

            Assert.NotNull(httpManager.GetConfig());

            var optimizely = new Optimizely(httpManager);

            var optimizelyConfig = optimizely.GetOptimizelyConfig();

            Assert.NotNull(optimizelyConfig);
            Assert.NotNull(optimizelyConfig.ExperimentsMap);
            Assert.NotNull(optimizelyConfig.FeaturesMap);
            Assert.NotNull(optimizelyConfig.Revision);

            optimizely.Dispose();

            var optimizelyConfigAfterDispose = optimizely.GetOptimizelyConfig();

            Assert.Null(optimizelyConfigAfterDispose);
        }
        public void TestHttpProjectConfigManagerDoesntRaiseExceptionForDefaultErrorHandler()
        {
            var t = MockSendAsync(TestData.Datafile);

            HttpProjectConfigManager httpManager = new HttpProjectConfigManager.Builder()
                                                   .WithSdkKey("10192104166")
                                                   .WithFormat("https://cdn.optimizely.com/json/{0}.json")
                                                   .WithLogger(LoggerMock.Object)
                                                   .WithPollingInterval(TimeSpan.FromMilliseconds(1000))
                                                   .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(500))
                                                   .WithStartByDefault()
                                                   .Build(true);

            t.Wait(1000);
            HttpClientMock.Verify(_ => _.SendAsync(
                                      It.Is <System.Net.Http.HttpRequestMessage>(requestMessage =>
                                                                                 requestMessage.RequestUri.ToString() == "https://cdn.optimizely.com/json/10192104166.json"
                                                                                 )));
            var datafileConfig = httpManager.GetConfig();

            Assert.IsNotNull(datafileConfig);
            Assert.IsNull(datafileConfig.GetExperimentFromKey("project_config_not_valid").Key);
            LoggerMock.Verify(_ => _.Log(LogLevel.DEBUG, "Making datafile request to url \"https://cdn.optimizely.com/json/10192104166.json\""));
            httpManager.Dispose();
        }
        public void TestEventProcessorWithBatchEventProcessorObj()
        {
            var eventDispatcher      = new DefaultEventDispatcher(LoggerMock.Object);
            var notificationCenter   = new NotificationCenter();
            var projectConfigManager = new HttpProjectConfigManager.Builder()
                                       .WithSdkKey("10192104166")
                                       .Build(true);

            var batchEventProcessor = new BatchEventProcessor.Builder()
                                      .WithLogger(LoggerMock.Object)
                                      .WithMaxBatchSize(20)
                                      .WithFlushInterval(TimeSpan.FromSeconds(3))
                                      .WithEventDispatcher(eventDispatcher)
                                      .WithNotificationCenter(notificationCenter)
                                      .Build();

            var optimizely = OptimizelyFactory.NewDefaultInstance(projectConfigManager, notificationCenter, eventProcessor: batchEventProcessor);

            var actualbatchEventProcessor   = Reflection.GetFieldValue <BatchEventProcessor, Optimizely>(optimizely, "EventProcessor");
            var actualEventProcessorProps   = new EventProcessorProps(actualbatchEventProcessor);
            var expectedEventProcessorProps = new EventProcessorProps(batchEventProcessor);

            Assert.AreEqual(actualEventProcessorProps, expectedEventProcessorProps);
            optimizely.Dispose();
        }
예제 #6
0
        public static Optimizely NewDefaultInstance()
        {
            var logger = OptimizelyLogger ?? new DefaultLogger();
            OptimizelySDKConfigSection OptlySDKConfigSection = null;

            try
            {
                OptlySDKConfigSection = ConfigurationManager.GetSection(ConfigSectionName) as OptimizelySDKConfigSection;
            }
            catch (ConfigurationErrorsException ex)
            {
                logger.Log(LogLevel.ERROR, "Invalid App.Config. Unable to initialize optimizely instance" + ex.Message);
                return(null);
            }

            HttpProjectConfigElement httpProjectConfigElement = OptlySDKConfigSection.HttpProjectConfig;

            if (httpProjectConfigElement == null)
            {
                return(null);
            }

            var errorHandler       = new DefaultErrorHandler(logger, false);
            var eventDispatcher    = new DefaultEventDispatcher(logger);
            var builder            = new HttpProjectConfigManager.Builder();
            var notificationCenter = new NotificationCenter();
            var configManager      = builder
                                     .WithSdkKey(httpProjectConfigElement.SDKKey)
                                     .WithUrl(httpProjectConfigElement.Url)
                                     .WithFormat(httpProjectConfigElement.Format)
                                     .WithPollingInterval(TimeSpan.FromMilliseconds(httpProjectConfigElement.PollingInterval))
                                     .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(httpProjectConfigElement.BlockingTimeOutPeriod))
#if !NET40 && !NET35
                                     .WithAccessToken(httpProjectConfigElement.DatafileAccessToken)
#endif
                                     .WithLogger(logger)
                                     .WithErrorHandler(errorHandler)
                                     .WithNotificationCenter(notificationCenter)
                                     .Build(true);

            EventProcessor eventProcessor = null;

            var batchEventProcessorElement = OptlySDKConfigSection.BatchEventProcessor;

            if (batchEventProcessorElement == null)
            {
                return(null);
            }

            eventProcessor = new BatchEventProcessor.Builder()
                             .WithMaxBatchSize(batchEventProcessorElement.BatchSize)
                             .WithFlushInterval(TimeSpan.FromMilliseconds(batchEventProcessorElement.FlushInterval))
                             .WithTimeoutInterval(TimeSpan.FromMilliseconds(batchEventProcessorElement.TimeoutInterval))
                             .WithLogger(logger)
                             .WithEventDispatcher(eventDispatcher)
                             .WithNotificationCenter(notificationCenter)
                             .Build();

            return(NewDefaultInstance(configManager, notificationCenter, eventDispatcher, errorHandler, logger, eventProcessor: eventProcessor));
        }
        public void TestOnReadyPromiseResolvedImmediatelyWhenDatafileIsProvided()
        {
            // Revision - 42
            var t = MockSendAsync(TestData.SimpleABExperimentsDatafile, TimeSpan.FromMilliseconds(100));

            HttpProjectConfigManager httpManager = new HttpProjectConfigManager.Builder()
                                                   // Revision - 15
                                                   .WithSdkKey("10192104166")
                                                   .WithDatafile(TestData.Datafile)
                                                   .WithLogger(LoggerMock.Object)
                                                   .WithPollingInterval(TimeSpan.FromMilliseconds(1000))
                                                   .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(500))
                                                   .WithStartByDefault()
                                                   .Build();

            // OnReady waits until is resolved, need to add time in case of deadlock.
            httpManager.OnReady().Wait(10000);

            Assert.AreEqual("15", httpManager.GetConfig().Revision);

            // loaded datafile from config manager after a second.
            // This wait triggers when SendAsync is triggered, OnReadyPromise is already resolved because of hardcoded datafile.
            t.Wait();
            Task.Delay(200).Wait();
            Assert.AreEqual("42", httpManager.GetConfig().Revision);
            httpManager.Dispose();
        }
예제 #8
0
        public static Optimizely NewDefaultInstance(string sdkKey, string fallback)
        {
            var logger             = OptimizelyLogger ?? new DefaultLogger();
            var errorHandler       = new DefaultErrorHandler();
            var eventDispatcher    = new DefaultEventDispatcher(logger);
            var builder            = new HttpProjectConfigManager.Builder();
            var notificationCenter = new NotificationCenter();

            var configManager = builder
                                .WithSdkKey(sdkKey)
                                .WithDatafile(fallback)
                                .WithLogger(logger)
                                .WithErrorHandler(errorHandler)
                                .WithNotificationCenter(notificationCenter)
                                .Build(true);

            EventProcessor eventProcessor = null;

#if !NETSTANDARD1_6 && !NET35
            eventProcessor = new BatchEventProcessor.Builder()
                             .WithLogger(logger)
                             .WithMaxBatchSize(MaxEventBatchSize)
                             .WithFlushInterval(MaxEventFlushInterval)
                             .WithEventDispatcher(eventDispatcher)
                             .WithNotificationCenter(notificationCenter)
                             .Build();
#endif

            return(NewDefaultInstance(configManager, notificationCenter, eventDispatcher, errorHandler, logger, eventProcessor: eventProcessor));
        }
        public void TestDefaultValuesWhenNotProvided()
        {
            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithDatafile(TestData.Datafile)
                              .WithLogger(LoggerMock.Object)
                              .Build(true);

            LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, $"No polling interval provided, using default period {TimeSpan.FromMinutes(5).TotalMilliseconds}ms"));
            LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, $"No Blocking timeout provided, using default blocking timeout {TimeSpan.FromSeconds(15).TotalMilliseconds}ms"));
            httpManager.Dispose();
        }
        public void TestDefaultPeriodWhileNotProvidingValue()
        {
            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithDatafile(TestData.Datafile)
                              .WithLogger(LoggerMock.Object)
                              .Build(true);

            var fieldInfo = typeof(PollingProjectConfigManager).GetField("PollingInterval", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            var expectedPollingInterval = (TimeSpan)fieldInfo.GetValue(httpManager);

            Assert.AreNotEqual(expectedPollingInterval.TotalSeconds, TimeSpan.Zero.TotalSeconds);

            LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, $"No polling interval provided, using default period {TimeSpan.FromMinutes(5).TotalMilliseconds}ms"));
            httpManager.Dispose();
        }
        public void TestDefaultBlockingTimeoutWhileNotProvidingValue()
        {
            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithDatafile(TestData.Datafile)
                              .WithLogger(LoggerMock.Object)
                              .Build(true);

            var fieldInfo = httpManager.GetType().GetField("BlockingTimeout", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            var expectedBlockingTimeout = (TimeSpan)fieldInfo.GetValue(httpManager);

            Assert.AreNotEqual(expectedBlockingTimeout.TotalSeconds, TimeSpan.Zero.TotalSeconds);

            LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, $"No Blocking timeout provided, using default blocking timeout {TimeSpan.FromSeconds(15).TotalMilliseconds}ms"));
            httpManager.Dispose();
        }
        public void TestHttpConfigManagerWithInvalidStatus()
        {
            var t = MockSendAsync(statusCode: HttpStatusCode.Forbidden);

            HttpProjectConfigManager httpManager = new HttpProjectConfigManager.Builder()
                                                   .WithUrl("https://cdn.optimizely.com/datafiles/QBw9gFM8oTn7ogY9ANCC1z.json")
                                                   .WithLogger(LoggerMock.Object)
                                                   .WithPollingInterval(TimeSpan.FromMilliseconds(1000))
                                                   .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(500))
                                                   .WithStartByDefault()
                                                   .Build();

            LoggerMock.Verify(_ => _.Log(LogLevel.ERROR, $"Error fetching datafile \"{HttpStatusCode.Forbidden}\""), Times.AtLeastOnce);

            httpManager.Dispose();
        }
        public void TestDefaultUrlWhenTokenNotProvided()
        {
            var t = MockSendAsync();

            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithLogger(LoggerMock.Object)
                              .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(50))
                              .Build(true);

            // it's to wait if SendAsync is not triggered.
            t.Wait(2000);
            HttpClientMock.Verify(_ => _.SendAsync(
                                      It.Is <System.Net.Http.HttpRequestMessage>(requestMessage =>
                                                                                 requestMessage.RequestUri.ToString() == "https://cdn.optimizely.com/datafiles/QBw9gFM8oTn7ogY9ANCC1z.json"
                                                                                 )));
            httpManager.Dispose();
        }
        public void TestHttpConfigManagerDoesNotSendConfigUpdateNotificationWhenDatafileIsProvided()
        {
            var t = MockSendAsync(TestData.Datafile, TimeSpan.FromMilliseconds(100));

            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithDatafile(TestData.Datafile)
                              .WithLogger(LoggerMock.Object)
                              .WithPollingInterval(TimeSpan.FromMilliseconds(1000))
                              .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(500))
                              .Build();


            httpManager.NotifyOnProjectConfigUpdate += NotificationCallbackMock.Object.TestConfigUpdateCallback;

            NotificationCallbackMock.Verify(nc => nc.TestConfigUpdateCallback(), Times.Never);
            Assert.NotNull(httpManager.GetConfig()); Assert.NotNull(httpManager.GetConfig());
            httpManager.Dispose();
        }
        public void TestProjectConfigManagerWithCustomProjectConfigManager()
        {
            var projectConfigManager = new HttpProjectConfigManager.Builder()
                                       .WithSdkKey("10192104166")
                                       .WithFormat("https://optimizely.com/json/{0}.json")
                                       .WithPollingInterval(TimeSpan.FromMilliseconds(3000))
                                       .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(4500))
                                       .WithStartByDefault()
                                       .WithAccessToken("access-token")
                                       .Build(true);

            var optimizely = OptimizelyFactory.NewDefaultInstance(projectConfigManager);
            var actualProjectConfigManager = optimizely.ProjectConfigManager as HttpProjectConfigManager;
            var actualConfigManagerProps   = new ProjectConfigManagerProps(actualProjectConfigManager);
            var expectedConfigManagerProps = new ProjectConfigManagerProps(projectConfigManager);

            Assert.AreEqual(actualConfigManagerProps, expectedConfigManagerProps);
            optimizely.Dispose();
        }
예제 #16
0
        /// <summary>
        /// Create optimizely client by set of parameters. Datafile will be updated from optimizely server
        /// </summary>
        /// <param name="createParameters"></param>
        /// <returns></returns>
        public static IOptimizely Create(OptimizelyClientCreateParameters createParameters)
        {
            if (createParameters == null)
            {
                throw new ArgumentNullException(nameof(createParameters));
            }

            var builder = new HttpProjectConfigManager.Builder()
                          .WithSdkKey(createParameters.SdkKey)
                          .WithStartByDefault();

            var projectConfigManager = builder
                                       .WithPollingInterval(TimeSpan.FromSeconds(createParameters.PollingPeriodInSeconds))
                                       .Build();

            var optimizely = new OptimizelySDK.Optimizely(projectConfigManager);

            return(new OptimizelyClient(optimizely));
        }
        public void TestFormatUrlHigherPriorityThanDefaultUrl()
        {
            var t           = MockSendAsync();
            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithLogger(LoggerMock.Object)
                              .WithFormat("http://customformat/{0}.json")
                              .WithAccessToken("datafile1")
                              .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(50))
                              .Build(true);

            // it's to wait if SendAsync is not triggered.
            t.Wait(2000);
            HttpClientMock.Verify(_ => _.SendAsync(
                                      It.Is <System.Net.Http.HttpRequestMessage>(requestMessage =>
                                                                                 requestMessage.RequestUri.ToString() == "http://customformat/QBw9gFM8oTn7ogY9ANCC1z.json"
                                                                                 )));
            httpManager.Dispose();
        }
        public void TestHttpConfigManagerSendConfigUpdateNotificationWhenProjectConfigGetsUpdated()
        {
            var t = MockSendAsync(TestData.Datafile);

            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithLogger(LoggerMock.Object)
                              .WithPollingInterval(TimeSpan.FromMilliseconds(1000))
                              .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(1000))
                              .WithStartByDefault(false)
                              .Build(true);

            httpManager.NotifyOnProjectConfigUpdate += NotificationCallbackMock.Object.TestConfigUpdateCallback;
            httpManager.Start();

            Assert.NotNull(httpManager.GetConfig());
            Task.Delay(200).Wait();
            NotificationCallbackMock.Verify(nc => nc.TestConfigUpdateCallback(), Times.AtLeastOnce);
            httpManager.Dispose();
        }
        public void TestAuthenticationHeaderWhenTokenProvided()
        {
            var t = MockSendAsync();

            var httpManager = new HttpProjectConfigManager.Builder()
                              .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                              .WithLogger(LoggerMock.Object)
                              .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(50))
                              .WithAccessToken("datafile1")
                              .Build(true);

            // it's to wait if SendAsync is not triggered.
            t.Wait(2000);

            HttpClientMock.Verify(_ => _.SendAsync(
                                      It.Is <System.Net.Http.HttpRequestMessage>(requestMessage =>
                                                                                 requestMessage.Headers.Authorization.ToString() == "Bearer datafile1"
                                                                                 )));
            httpManager.Dispose();
        }
        public void TestHttpConfigManagerRetreiveProjectConfigBySDKKey()
        {
            var t = MockSendAsync(TestData.Datafile);

            HttpProjectConfigManager httpManager = new HttpProjectConfigManager.Builder()
                                                   .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                                                   .WithLogger(LoggerMock.Object)
                                                   .WithPollingInterval(TimeSpan.FromMilliseconds(1000))
                                                   .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(500))
                                                   .WithStartByDefault()
                                                   .Build();

            t.Wait(1000);
            HttpClientMock.Verify(_ => _.SendAsync(
                                      It.Is <System.Net.Http.HttpRequestMessage>(requestMessage =>
                                                                                 requestMessage.RequestUri.ToString() == "https://cdn.optimizely.com/datafiles/QBw9gFM8oTn7ogY9ANCC1z.json"
                                                                                 )));
            Assert.IsNotNull(httpManager.GetConfig());
            httpManager.Dispose();
        }
        public void TestOnReadyPromiseWaitsForProjectConfigRetrievalWhenDatafileIsNotProvided()
        {
            // Revision - 42
            var t = MockSendAsync(TestData.SimpleABExperimentsDatafile, TimeSpan.FromMilliseconds(1000));

            HttpProjectConfigManager httpManager = new HttpProjectConfigManager.Builder()
                                                   .WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
                                                   .WithLogger(LoggerMock.Object)
                                                   .WithPollingInterval(TimeSpan.FromSeconds(2))
                                                   .WithBlockingTimeoutPeriod(TimeSpan.FromSeconds(1))
                                                   .WithStartByDefault(true)
                                                   .Build();

            t.Wait();

            // OnReady waits until is resolved, need to add time in case of deadlock.
            httpManager.OnReady().Wait(10000);
            Assert.NotNull(httpManager.GetConfig());
            httpManager.Dispose();
        }
        public void TestHttpConfigManagerRetreiveProjectConfigByURL()
        {
            var t = MockSendAsync(TestData.Datafile);
            HttpProjectConfigManager httpManager = new HttpProjectConfigManager.Builder()
                                                   .WithUrl("https://cdn.optimizely.com/datafiles/QBw9gFM8oTn7ogY9ANCC1z.json")
                                                   .WithLogger(LoggerMock.Object)
                                                   .WithPollingInterval(TimeSpan.FromMilliseconds(1000))
                                                   .WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(500))
                                                   .WithStartByDefault()
                                                   .Build();

            // This method waits until SendAsync is not triggered.
            // Time is given here to avoid hanging-up in any worst case.
            t.Wait(1000);

            HttpClientMock.Verify(_ => _.SendAsync(
                                      It.Is <System.Net.Http.HttpRequestMessage>(requestMessage =>
                                                                                 requestMessage.RequestUri.ToString() == "https://cdn.optimizely.com/datafiles/QBw9gFM8oTn7ogY9ANCC1z.json"
                                                                                 )));
            httpManager.Dispose();
        }