public void TestSingleActionDSUploadSingleEvent()
        {
            joinServer.Reset();

            string uniqueKey = "test interaction";

            var dsConfig = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionServiceConfiguration<TestContext>(
                authorizationToken: MockCommandCenter.AuthorizationToken,
                explorer: new Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction.EpsilonGreedyExplorer<TestContext>(new TestSingleActionPolicy(), epsilon: 0.2f, numActions: Constants.NumberOfActions));

            dsConfig.JoinServerType = JoinServerType.CustomSolution;
            dsConfig.LoggingServiceAddress = MockJoinServer.MockJoinServerAddress;

            var ds = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionService<TestContext>(dsConfig);

            uint chosenAction = ds.ChooseAction(new UniqueEventID { Key = uniqueKey }, new TestContext());

            ds.Flush();

            Assert.AreEqual(1, joinServer.RequestCount);
            Assert.AreEqual(1, joinServer.EventBatchList.Count);
            Assert.AreEqual(1, joinServer.EventBatchList[0].ExperimentalUnitFragments.Count);
            Assert.AreEqual(uniqueKey, joinServer.EventBatchList[0].ExperimentalUnitFragments[0].Id);
            Assert.IsTrue(joinServer.EventBatchList[0].ExperimentalUnitFragments[0].Value.ToLower().Contains("\"a\":" + chosenAction + ","));
        }
Пример #2
0
        public void TestSingleActionInvalidPathOutputDir()
        {
            joinServer.Reset();

            commandCenter.CreateBlobs(createSettingsBlob: true, createModelBlob: false);

            var dsConfig = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionServiceConfiguration<TestContext>(
                authorizationToken: MockCommandCenter.AuthorizationToken,
                explorer: new Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction.EpsilonGreedyExplorer<TestContext>(new TestSingleActionPolicy(), epsilon: 0.2f, numActions: 2));

            dsConfig.JoinServerType = JoinServerType.CustomSolution;
            dsConfig.LoggingServiceAddress = MockJoinServer.MockJoinServerAddress;
            dsConfig.BlobOutputDir = @"c:\";
            dsConfig.PollingForSettingsPeriod = TimeSpan.FromMilliseconds(500);

            var cancelTokenSource = new CancellationTokenSource();
            bool exceptionIsExpected = false;

            dsConfig.SettingsPollFailureCallback = (ex) => 
            {
                if (ex is ArgumentNullException && ((ArgumentNullException)ex).ParamName == "path")
                {
                    exceptionIsExpected = true;
                    cancelTokenSource.Cancel();
                }
            };

            var ds = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionService<TestContext>(dsConfig);

            cancelTokenSource.Token.WaitHandle.WaitOne(5000);

            Assert.AreEqual(true, exceptionIsExpected);
        }
Пример #3
0
        public void TestSingleActionSettingsBlobOutput()
        {
            joinServer.Reset();

            string settingsPath = ".\\dstestsettings";
            Directory.CreateDirectory(settingsPath);

            commandCenter.CreateBlobs(createSettingsBlob: true, createModelBlob: false);

            var dsConfig = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionServiceConfiguration<TestContext>(
                authorizationToken: MockCommandCenter.AuthorizationToken,
                explorer: new Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction.EpsilonGreedyExplorer<TestContext>(new TestSingleActionPolicy(), epsilon: 0.2f, numActions: 2));

            dsConfig.JoinServerType = JoinServerType.CustomSolution;
            dsConfig.LoggingServiceAddress = MockJoinServer.MockJoinServerAddress;
            dsConfig.BlobOutputDir = settingsPath;
            dsConfig.PollingForSettingsPeriod = TimeSpan.FromMilliseconds(500);

            var ds = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionService<TestContext>(dsConfig);

            string settingsFile = Path.Combine(settingsPath, "settings-" + commandCenter.LocalAzureSettingsBlobName);

            int sleepCount = 20;
            while (true && sleepCount > 0)
            {
                Thread.Sleep(100);
                sleepCount--;

                if (File.Exists(settingsFile))
                {
                    break;
                }
            }

            Assert.AreNotEqual(0, sleepCount);

            while (true)
            {
                try
                {
                    byte[] settingsBytes = File.ReadAllBytes(settingsFile);

                    Assert.IsTrue(Enumerable.SequenceEqual(settingsBytes, commandCenter.GetSettingsBlobContent()));
                    break;
                }
                catch (IOException) { }
            }

            ds.Flush();

            Directory.Delete(settingsPath, true);
        }
Пример #4
0
        public void TestSingleActionOfflineModeArgument()
        {
            var dsConfig = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionServiceConfiguration<TestContext>(
                authorizationToken: "my token",
                explorer: new Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction.EpsilonGreedyExplorer<TestContext>(new TestSingleActionPolicy(), epsilon: 0.2f, numActions: 2));

            dsConfig.OfflineMode = true;

            try
            {
                var ds = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionService<TestContext>(dsConfig);
            }
            catch (ArgumentException ex)
            {
                Assert.AreEqual("Recorder", ex.ParamName);
            }
        }
Пример #5
0
        public void TestSingleActionOfflineModeCustomLogger()
        {
            var dsConfig = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionServiceConfiguration<TestContext>(
                authorizationToken: "my token",
                explorer: new Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction.EpsilonGreedyExplorer<TestContext>(new TestSingleActionPolicy(), epsilon: 0.2f, numActions: Constants.NumberOfActions));

            dsConfig.OfflineMode = true;
            dsConfig.Recorder = new TestLogger();

            int numChooseAction = 100;
            var ds = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionService<TestContext>(dsConfig); 
            for (int i = 0; i < numChooseAction; i++)
            {
                ds.ChooseAction(new UniqueEventID { Key = i.ToString() }, new TestContext());
            }

            Assert.AreEqual(numChooseAction, ((TestLogger)dsConfig.Recorder).NumRecord);

            int numReward = 200;
            for (int i = 0; i < numReward; i++)
            {
                ds.ReportReward(i, new UniqueEventID { Key = i.ToString() });
            }

            Assert.AreEqual(numReward, ((TestLogger)dsConfig.Recorder).NumReward);

            int numOutcome = 300;
            for (int i = 0; i < numOutcome; i++)
            {
                ds.ReportOutcome(i.ToString(), new UniqueEventID { Key = i.ToString() });
            }

            Assert.AreEqual(numOutcome, ((TestLogger)dsConfig.Recorder).NumOutcome);

            ds.Flush();

            Assert.AreEqual(0, ((TestLogger)dsConfig.Recorder).NumRecord);
            Assert.AreEqual(0, ((TestLogger)dsConfig.Recorder).NumReward);
            Assert.AreEqual(0, ((TestLogger)dsConfig.Recorder).NumOutcome);
        }
        public void TestSingleActionDSUploadMultipleEvents()
        {
            joinServer.Reset();

            string uniqueKey = "test interaction";

            var dsConfig = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionServiceConfiguration<TestContext>(
                authorizationToken: MockCommandCenter.AuthorizationToken,
                explorer: new Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction.EpsilonGreedyExplorer<TestContext>(new TestSingleActionPolicy(), epsilon: 0.2f, numActions: Constants.NumberOfActions));

            dsConfig.JoinServerType = JoinServerType.CustomSolution;
            dsConfig.LoggingServiceAddress = MockJoinServer.MockJoinServerAddress;

            var ds = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionService<TestContext>(dsConfig);

            uint chosenAction1 = ds.ChooseAction(new UniqueEventID { Key = uniqueKey }, new TestContext());
            uint chosenAction2 = ds.ChooseAction(new UniqueEventID { Key = uniqueKey }, new TestContext());
            ds.ReportReward(1.0f, new UniqueEventID { Key = uniqueKey });
            ds.ReportOutcome(JsonConvert.SerializeObject(new { value = "test outcome" }), new UniqueEventID { Key = uniqueKey });

            ds.Flush();

            Assert.AreEqual(4, joinServer.EventBatchList.Sum(batch => batch.ExperimentalUnitFragments.Count));
        }
Пример #7
0
        public void TestSingleActionOnlineModeInvalidToken()
        {
            MockCommandCenter.UnsetRedirectionBlobLocation();

            var dsConfig = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionServiceConfiguration<TestContext>(
                authorizationToken: MockCommandCenter.AuthorizationToken,
                explorer: new Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction.EpsilonGreedyExplorer<TestContext>(new TestSingleActionPolicy(), epsilon: 0.2f, numActions: Constants.NumberOfActions));
            dsConfig.JoinServerType = JoinServerType.CustomSolution;

            bool isExceptionExpected = false;
            try
            {
                var ds = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionService<TestContext>(dsConfig);
            }
            catch (InvalidDataException)
            {
                isExceptionExpected = true;
            }
            Assert.AreEqual(true, isExceptionExpected);
        }
        public void TestSingleActionDSThreadSafeUpload()
        {
            joinServer.Reset();

            string uniqueKey = "test interaction";

            var createObservation = (Func<int, string>)((i) => { return string.Format("00000", i); });

            var dsConfig = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionServiceConfiguration<TestContext>(
                authorizationToken: MockCommandCenter.AuthorizationToken,
                explorer: new Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction.EpsilonGreedyExplorer<TestContext>(new TestSingleActionPolicy(), epsilon: 0.2f, numActions: Constants.NumberOfActions));

            dsConfig.JoinServerType = JoinServerType.CustomSolution;
            dsConfig.LoggingServiceAddress = MockJoinServer.MockJoinServerAddress;

            var ds = new Microsoft.Research.MultiWorldTesting.ClientLibrary.SingleAction.DecisionService<TestContext>(dsConfig);

            int numEvents = 1000;

            var chosenActions = new ConcurrentBag<uint>();

            Parallel.For(0, numEvents, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 }, (i) =>
            {
                chosenActions.Add(ds.ChooseAction(new UniqueEventID { Key = uniqueKey }, new TestContext()));
                ds.ReportOutcome(new { value = createObservation(i) }, new UniqueEventID { Key = uniqueKey });
            });

            ds.Flush();

            List<PartialDecisionServiceMessage> batchList = this.joinServer.EventBatchList;
            int numActualEvents = batchList.Sum(b => b.ExperimentalUnitFragments.Count);
            Assert.AreEqual(numEvents * 2, numActualEvents);

            List<string> uniqueKeys = batchList
                .SelectMany(b => b.ExperimentalUnitFragments.Select(f => f.Id))
                .Distinct()
                .ToList();

            Assert.AreEqual(1, uniqueKeys.Count);
            Assert.AreEqual(uniqueKey, uniqueKeys[0]);

            var completeFragments = batchList
                .SelectMany(b => b.ExperimentalUnitFragments
                .Select(f => JsonConvert.DeserializeObject<SingleActionCompleteExperimentalUnitFragment>(f.Value)));

            // Test actual interactions received 
            List<SingleActionCompleteExperimentalUnitFragment> interactions = completeFragments
                .Where(f => f.Value == null)
                .OrderBy(f => f.Action)
                .ToList();

            // Test values of the interactions
            Assert.AreEqual(numEvents, interactions.Count);
            var chosenActionList = chosenActions.OrderBy(a => a).ToList();
            for (int i = 0; i < interactions.Count; i++)
            {
                Assert.AreEqual((int)chosenActionList[i], interactions[i].Action.Value);
            }

            // Test actual observations received
            List<SingleActionCompleteExperimentalUnitFragment> observations = completeFragments
                .Where(f => f.Value != null)
                .OrderBy(f => f.Value)
                .ToList();

            // Test values of the observations
            Assert.AreEqual(numEvents, observations.Count);
            for (int i = 0; i < observations.Count; i++)
            {
                Assert.AreEqual(JsonConvert.SerializeObject(new { value = createObservation(i) }), observations[i].Value);
            }
        }