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 + ",")); }
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); }
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); }
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); } }
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)); }
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); } }