public void Test_AsyncSender_SendSuccess()
        {
            ManualResetEventSlim senderCalledWaiter = new ManualResetEventSlim(initialState: false);

            bool sendCalled = false;

            Task AsyncSenderSend(SharedBuffer buffer, BackgroundErrorCallback raiseBackgroundError)
            {
                sendCalled = true;
                senderCalledWaiter.Set();

                return(Task.CompletedTask);
            }

            FactoryContext factoryContext = CreateFactoryContext(asyncSendFunc: AsyncSenderSend);

            LiveModel liveModel = CreateLiveModel(factoryContext);

            liveModel.Init();
            RankingResponse response = liveModel.ChooseRank(EventId, ContextJsonWithPdf);

            senderCalledWaiter.Wait(TimeSpan.FromSeconds(1));

            Assert.IsTrue(sendCalled);
        }
Exemple #2
0
        private LiveModel ConfigureLiveModel()
        {
            Configuration config;
            ApiStatus     apiStatus = new ApiStatus();

            if (!Configuration.TryLoadConfigurationFromJson(PseudoLocConfigJson, out config, apiStatus))
            {
                Assert.Fail("Failed to parse pseudolocalized configuration JSON: " + apiStatus.ErrorMessage);
            }

            TempFileDisposable interactionDisposable = new TempFileDisposable();

            this.TestCleanup.Add(interactionDisposable);

            TempFileDisposable observationDisposable = new TempFileDisposable();

            this.TestCleanup.Add(observationDisposable);

            config["interaction.file.name"] = interactionDisposable.Path;
            config["observation.file.name"] = observationDisposable.Path;

            LiveModel liveModel = new LiveModel(config);

            liveModel.Init();
            liveModel.RefreshModel();

            return(liveModel);
        }
        public void Test_CustomSender_InitSuccess()
        {
            bool initCalled = false;

            void SenderInit(ApiStatus status)
            {
                initCalled = true;
            }

            FactoryContext factoryContext = CreateFactoryContext(initAction: SenderInit);

            LiveModel liveModel = CreateLiveModel(factoryContext);

            liveModel.Init();

            Assert.IsTrue(initCalled, "MockSender.Init should be called and succeed, which means LiveModel.Init should succeed.");
        }
        /// <summary> Gets the rank processor initiated with live model to use </summary>
        internal virtual RlNetProcessor GetConfigurationForRankProcessor(CancellationToken cancellationToken = default)
        {
            Configuration config = new Configuration();

            // set up the model
            if (azureKeyCredential != null)
            {
                config["http.api.key"] = azureKeyCredential.Key;
            }
            else if (tokenCredential != null)
            {
                var         tokenRequestContext = new TokenRequestContext(scopes);
                AccessToken token = tokenCredential.GetToken(tokenRequestContext, cancellationToken);
                config["http.api.key"]             = "Bearer " + token.Token;
                config["http.api.header.key.name"] = "Authorization";
                tokenExpiry = token.ExpiresOn;
            }
            else
            {
                throw new ApplicationException("PersonalizerClient is neither initalized with Token Credential nor with AzureKey Credential");
            }
            personalizerServiceProperties = ServiceConfigurationRestClient.Get(cancellationToken);
            personalizerPolicy            = PolicyRestClient.Get(cancellationToken);
            //interactions & observations
            config["interaction.http.api.host"]         = stringEndpoint + "personalizer/v1.1-preview.3/logs/interactions";
            config["observation.http.api.host"]         = stringEndpoint + "personalizer/v1.1-preview.3/logs/observations";
            config["interaction.sender.implementation"] = "INTERACTION_HTTP_API_SENDER";
            config["observation.sender.implementation"] = "OBSERVATION_HTTP_API_SENDER";
            config["interaction.subsample.rate"]        = Convert.ToString(this.subsampleRate, CultureInfo.InvariantCulture);
            config["observation.subsample.rate"]        = Convert.ToString(this.subsampleRate, CultureInfo.InvariantCulture);
            //model
            config["model.blob.uri"] = stringEndpoint + "personalizer/v1.1-preview.3/model";
            config["model.source"]   = "HTTP_MODEL_DATA";

            config["model.vw.initial_command_line"] = personalizerPolicy.Arguments;
            config["protocol.version"]            = "2";
            config["initial_exploration.epsilon"] = Convert.ToString(personalizerServiceProperties.ExplorationPercentage, CultureInfo.InvariantCulture);
            config["rank.learning.mode"]          = Convert.ToString(personalizerServiceProperties.LearningMode, CultureInfo.InvariantCulture);
            LiveModel liveModel = new LiveModel(config);

            liveModel.Init();
            LiveModelBase liveModelAdapter = new LiveModelAdapter(liveModel);

            liveModelLastRefresh = DateTimeOffset.UtcNow;
            return(new RlNetProcessor(liveModelAdapter));
        }
        private void Run_TestCustomSender_SendFailure(FactoryContext factoryContext, string expectedString, bool expectPrefix = false)
        {
            ManualResetEventSlim backgroundMessageWaiter = new ManualResetEventSlim(initialState: false);

            int    backgroundErrorCount   = 0;
            int    backgroundErrorCode    = 0;
            string backgroundErrorMessage = null;

            void OnBackgroundError(object sender, ApiStatus args)
            {
                Assert.AreEqual(0, backgroundErrorCount++, "Do not duplicate background errors.");
                backgroundErrorCode    = args.ErrorCode;
                backgroundErrorMessage = args.ErrorMessage;

                backgroundMessageWaiter.Set();
            }

            LiveModel liveModel = CreateLiveModel(factoryContext);

            liveModel.BackgroundError += OnBackgroundError;

            liveModel.Init();

            ApiStatus       apiStatus = new ApiStatus();
            RankingResponse response;

            Assert.IsTrue(liveModel.TryChooseRank(EventId, ContextJsonWithPdf, out response, apiStatus));
            Assert.AreEqual(NativeMethods.SuccessStatus, apiStatus.ErrorCode, "Errors from ISender.Send should be background errors.");

            backgroundMessageWaiter.Wait(TimeSpan.FromSeconds(1));

            Assert.AreEqual(NativeMethods.OpaqueBindingError, backgroundErrorCode, "Error from ISender did not get raised.");

            if (!expectPrefix)
            {
                Assert.AreEqual(OpaqueErrorMessage, backgroundErrorMessage);
            }
            else
            {
                Assert.IsTrue(backgroundErrorMessage.StartsWith(OpaqueErrorMessage));
            }
        }
        public void Test_CustomSender_FactoryCalled_WhenRequested()
        {
            ApiStatus apiStatus = new ApiStatus();

            bool           factoryCalled  = false;
            FactoryContext factoryContext = CreateFactoryContext(
                (IReadOnlyConfiguration config, ErrorCallback callback) =>
            {
                factoryCalled = true;

                return(new MockSender());
            });


            LiveModel liveModel = CreateLiveModel(factoryContext);

            liveModel.Init();

            Assert.IsTrue(factoryCalled, "Custom factory must be called when BINDING_SENDER is selected in configuration.");
        }
        public void Test_CustomSender_FactoryNotCalled_WhenNotRequested()
        {
            ApiStatus apiStatus = new ApiStatus();

            FactoryContext factoryContext = new FactoryContext();

            bool factoryCalled = false;
            Func <IReadOnlyConfiguration, ErrorCallback, MockSender> customFactory =
                (IReadOnlyConfiguration readOnlyConfig, ErrorCallback callback) =>
            {
                factoryCalled = true;

                return(new MockSender());
            };

            Configuration config = new Configuration();

            if (!Configuration.TryLoadConfigurationFromJson(FileSenderConfigJson, out config, apiStatus))
            {
                Assert.Fail("Failed to parse pseudolocalized configuration JSON: " + apiStatus.ErrorMessage);
            }

            TempFileDisposable interactionDisposable = new TempFileDisposable();

            this.TestCleanup.Add(interactionDisposable);

            TempFileDisposable observationDisposable = new TempFileDisposable();

            this.TestCleanup.Add(observationDisposable);

            config["interaction.file.name"] = interactionDisposable.Path;
            config["observation.file.name"] = observationDisposable.Path;

            factoryContext.SetSenderFactory(customFactory);

            LiveModel liveModel = new LiveModel(config, factoryContext);

            liveModel.Init();

            Assert.IsFalse(factoryCalled, "Custom factory should not be called unless BINDING_SENDER is selected in configuration.");
        }
        public void Test_CustomSender_SendSuccess()
        {
            ManualResetEventSlim senderCalledWaiter = new ManualResetEventSlim(initialState: false);

            bool sendCalled = false;

            void SenderSend(SharedBuffer buffer, ApiStatus status)
            {
                sendCalled = true;
                senderCalledWaiter.Set();
            }

            FactoryContext factoryContext = CreateFactoryContext(sendAction: SenderSend);

            LiveModel liveModel = CreateLiveModel(factoryContext);

            liveModel.Init();
            RankingResponse response = liveModel.ChooseRank(EventId, ContextJsonWithPdf);

            senderCalledWaiter.Wait(TimeSpan.FromSeconds(1));

            Assert.IsTrue(sendCalled);
        }
 /// <summary> Init LiveModel </summary>
 public override void Init()
 {
     liveModel.Init();
 }