public void MarkAsUnRemovable(Market market) { if (market == null || _unRemovables.Contains(market)) return; _unRemovables.Add(market); }
private void SetSelectionIds(Market firstMarket, Market currentMarketIndex, string selectionIndexTag) { foreach (var selection in currentMarketIndex.Selections) { // tag selection matching by tags var matchingSelection = firstMarket.Selections.First(s => s.Tags.All(tag => TagEquals(selectionIndexTag, tag, selection))); _selections[selection.Id] = matchingSelection.Id; } }
public void WhenUpdateArrives(Table table) { var market = new Market {Id = "TestId"}; market.AddOrUpdateTagValue("name", "TestMarket"); market.Selections.Clear(); market.Selections.AddRange(table.Rows.Select(r=> Helper.GetObjectFromTableRow<Selection>(r))); _fixture.Markets.Clear(); _fixture.Markets.Add(market); }
public void GivenIHaveThisMarket(Table table) { Market market = new Market(); market.Id = "ABC"; if (table.Rows.Count > 0) market.Id = table.Rows[0]["Value"]; if (ScenarioContext.Current.ContainsKey("Market")) ScenarioContext.Current.Remove("Market"); ScenarioContext.Current.Add("Market", market); }
public IndexMapping(Market firstMarket, Market firstActiveMarket, Market currentMarketIndex, int index, string nextMarketId, string selectionIndexTag, string marketName) { Index = index; MarketId = firstMarket.Id; NextMarketId = nextMarketId; MarketName = marketName; if (firstActiveMarket.Id == currentMarketIndex.Id) IsCurrent = true; SetSelectionIds(firstMarket, currentMarketIndex, selectionIndexTag); }
private static Market CreateSuspendedMarket(IMarketState MarketState) { var market = new Market(MarketState.Id) {IsSuspended = true}; if (MarketState.HasTag("line")) { market.AddOrUpdateTagValue("line", MarketState.GetTagValue("line")); } foreach (var stateSelection in MarketState.Selections) market.Selections.Add(new Selection { Id = stateSelection.Id, Status = SelectionStatus.Pending, Tradable = false, Price = 0 }); return market; }
public void AddMarket(Market market, MarketRuleAddIntent addIntent) { if (market == null || _added.ContainsKey(market)) return; _added.Add(market,addIntent); }
public void PostRuleProcessingTest() { // This test sets up a dummy market rule that removes // all the markets whose Id start with "REMOVE". // The test, after calling ApplyRules() on the MarketRuleManager // checks if the property "HasBeenProcessed" is set to true // for all the markets whose Id don't start with REMOVE. // // The HasBeenProcessed property is set to true only // when a market has been passed at least once to the // plugin, or in other words, the outcome of the // MarketRuleManager hasn't remove it from the Fixture object. // This property is set on IUpdatableMarketState.ApplyPostRulesProcessing() Mock<IMarketRule> aRule = new Mock<IMarketRule>(); aRule.Setup(x => x.Apply(It.IsAny<Fixture>(), It.IsAny<IMarketStateCollection>(), It.IsAny<IMarketStateCollection>())) .Returns((Fixture f, IMarketStateCollection nS, IMarketStateCollection oS) => { MarketRuleResultIntent intent = new MarketRuleResultIntent(); foreach(var mkt in f.Markets) { if(mkt.Id.StartsWith("REMOVE")) intent.MarkAsRemovable(mkt); } return intent; } ); var settings = new Mock<ISettings>(); var plugin = new Mock<IAdapterPlugin>(); var stateprovider = new StateManager(settings.Object, plugin.Object); List<IMarketRule> rules = new List<IMarketRule> { aRule.Object }; Fixture fixture = new Fixture { Id = "ABC", MatchStatus = "30"}; Market testMkt = new Market { Id = "1"}; fixture.Markets.Add(testMkt); testMkt = new Market { Id = "REMOVE-1" }; fixture.Markets.Add(testMkt); testMkt = new Market { Id = "2" }; fixture.Markets.Add(testMkt); testMkt = new Market { Id = "REMOVE-2" }; fixture.Markets.Add(testMkt); MarketRulesManager manager = new MarketRulesManager(fixture.Id, stateprovider, rules); manager.ApplyRules(fixture); manager.CurrentState["1"].Should().NotBeNull(); manager.CurrentState["1"].HasBeenProcessed.Should().BeTrue(); manager.CurrentState["2"].Should().NotBeNull(); manager.CurrentState["2"].HasBeenProcessed.Should().BeTrue(); manager.CurrentState["REMOVE-1"].Should().NotBeNull(); manager.CurrentState["REMOVE-1"].HasBeenProcessed.Should().BeFalse(); manager.CurrentState["REMOVE-2"].Should().NotBeNull(); manager.CurrentState["REMOVE-2"].HasBeenProcessed.Should().BeFalse(); manager.CommitChanges(); manager.CurrentState["1"].Should().NotBeNull(); manager.CurrentState["1"].HasBeenProcessed.Should().BeTrue(); manager.CurrentState["2"].Should().NotBeNull(); manager.CurrentState["2"].HasBeenProcessed.Should().BeTrue(); manager.CurrentState["REMOVE-1"].Should().NotBeNull(); manager.CurrentState["REMOVE-1"].HasBeenProcessed.Should().BeFalse(); manager.CurrentState["REMOVE-2"].Should().NotBeNull(); manager.CurrentState["REMOVE-2"].HasBeenProcessed.Should().BeFalse(); }
public void SuspendFixtureOnStreamListenerDisposeTest() { // STEP 1: prepare stub data Mock<IResourceFacade> resource = new Mock<IResourceFacade>(); Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>(); Mock<IEventState> state = new Mock<IEventState>(); Mock<ISettings> settings = new Mock<ISettings>(); var provider = new StateManager(settings.Object, connector.Object); provider.SuspensionManager.RegisterAction(provider.SuspensionManager.SuspendInPlayMarketsStrategy, SuspensionReason.DISCONNECT_EVENT); // STEP 3: prepare the fixture data Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() }; fixture.Tags.Add("Sport", "Football"); // add at least one tags, so the MarketsRulesManager recognize it as a full-snapshot fixture.Markets.Add(new Market("MKT-1")); var mkt = new Market("MKT-2"); mkt.AddOrUpdateTagValue("traded_in_play", "false"); fixture.Markets.Add(mkt); resource.Setup(x => x.Id).Returns("ABC"); resource.Setup(x => x.Content).Returns(new Summary()); resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty); resource.Setup(x => x.StopStreaming()).Raises(x => x.StreamDisconnected += null, EventArgs.Empty); resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)); // STEP 4: start the listener StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,settings.Object); listener.Start(); listener.IsStreaming.Should().BeTrue(); connector.Verify(x => x.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never); listener.Dispose(); connector.Verify(x=> x.Suspend(It.IsAny<string>()),Times.Once); //// STEP 5: check the result, note tha MKT-2 is not in-play //connector.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture>( // y => y.Id == "ABC" && // y.Markets.Count == 1 && // y.Markets.FirstOrDefault(z => z.Id == "MKT-1") != null), // It.IsAny<bool>()), Times.Once); }
public void DontSendSuspensionOnDisposingIfFixtureEndedOrDeletedTest() { // STEP 1: prepare data Mock<IResourceFacade> resource = new Mock<IResourceFacade>(); Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>(); Mock<IEventState> state = new Mock<IEventState>(); var provider = new StateManager(_settings.Object, connector.Object); bool disposed = false; bool matchover = false; bool deleted = false; Action<IMarketStateCollection> disponsing_strategy = x => {disposed = true;}; Action<IMarketStateCollection> matchover_strategy = x => { matchover = true; }; Action<IMarketStateCollection> deleted_strategy = x => { deleted = true; }; provider.SuspensionManager.RegisterAction(disponsing_strategy, SuspensionReason.FIXTURE_DISPOSING); provider.SuspensionManager.RegisterAction(deleted_strategy, SuspensionReason.FIXTURE_DELETED); provider.SuspensionManager.RegisterAction(matchover_strategy, SuspensionReason.SUSPENSION); Fixture fixture = new Fixture { Id = "ABCDE", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = 1 }; Market mkt = new Market { Id = "MKT" }; fixture.Markets.Add(mkt); Fixture update = new Fixture { Id = "ABCDE", Sequence = 2, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = 2, LastEpochChangeReason = new[] { (int)EpochChangeReason.Deleted } }; StreamMessage message = new StreamMessage { Content = update }; resource.Setup(x => x.Id).Returns("ABCDE"); resource.Setup(x => x.Content).Returns(new Summary()); resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty); resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)); // STEP 2: start the listener StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,_settings.Object); listener.Start(); listener.IsStreaming.Should().BeTrue(); disposed.Should().BeFalse(); matchover.Should().BeFalse(); deleted.Should().BeFalse(); // STEP 3: send a delete command and check the result listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message))); //Update snapshot sequence fixture.Sequence = 2; resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)); disposed.Should().BeFalse(); matchover.Should().BeFalse(); deleted.Should().BeTrue(); // STEP 4: reset the flags and send the dispose command // (no other suspension commands should be raised); disposed = false; matchover = false; deleted = false; listener.Dispose(); deleted.Should().BeFalse(); disposed.Should().BeFalse(); matchover.Should().BeFalse(); // STEP 5: do the same, but for MatchOver disposed = false; matchover = false; deleted = false; listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object); listener.Start(); listener.IsStreaming.Should().BeTrue(); disposed.Should().BeFalse(); matchover.Should().BeFalse(); deleted.Should().BeFalse(); update = new Fixture { Id = "ABCDE", Sequence = 2, MatchStatus = ((int)MatchStatus.MatchOver).ToString(), Epoch = 2, LastEpochChangeReason = new[] { (int)EpochChangeReason.MatchStatus } }; message = new StreamMessage { Content = update }; // STEP 3: send a delete command and check the result listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message))); disposed.Should().BeFalse(); matchover.Should().BeTrue(); deleted.Should().BeFalse(); // STEP 4: reset the flags and send the dispose command // (no other suspension commands should be raised); disposed = false; matchover = false; deleted = false; listener.Dispose(); deleted.Should().BeFalse(); disposed.Should().BeFalse(); matchover.Should().BeFalse(); }
private void MergeSelectionStates(Market market, bool fullSnapshot) { if (market.Selections == null) return; foreach (var selection in market.Selections) { if (_selectionStates.ContainsKey(selection.Id)) _selectionStates[selection.Id].Update(selection, fullSnapshot); else { _selectionStates[selection.Id] = new SelectionState(selection, fullSnapshot); } } }
private void UpdateLineOnRollingHandicap(Market market) { var rollingHandicap = market as RollingMarket; if (rollingHandicap == null) return; var oneLine = _selectionStates.Values.All(s => s.Line == _selectionStates.Values.First().Line); if (oneLine) rollingHandicap.Line = rollingHandicap.Selections.First().Line; else { var selectionWithHomeTeam = _selectionStates.Values.FirstOrDefault(s => s.HasTag("team") && s.GetTagValue("team") == "1"); if (selectionWithHomeTeam == null) throw new ArgumentException(string.Format("Rolling handicap line for market {0} can't be verified", market)); var homeSelection = rollingHandicap.Selections.FirstOrDefault(s => s.Id == selectionWithHomeTeam.Id); //during update we may not receive an update for all selections if (homeSelection != null) { rollingHandicap.Line = homeSelection.Line; } else { var selectionWithAwayTeam = _selectionStates.Values.FirstOrDefault(s => s.HasTag("team") && s.GetTagValue("team") == "2"); // invert the line rollingHandicap.Line = selectionWithAwayTeam.Line * (-1); } } this.Line = rollingHandicap.Line; }
public void Update(Market market, bool fullSnapshot) { MergeSelectionStates(market, fullSnapshot); if (fullSnapshot) { _tags = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); foreach (var key in market.TagKeys) _tags.Add(key, market.GetTagValue(key)); if (_tags.ContainsKey("traded_in_play")) IsTradedInPlay = string.Equals(_tags["traded_in_play"], "true", StringComparison.InvariantCultureIgnoreCase); } // always set to false at each update IsForcedSuspended = false; market.IsPending = IsPending; market.IsActive = IsActive; market.IsResulted = IsResulted; market.IsSuspended = IsSuspended; market.IsTradedInPlay = IsTradedInPlay; market.IsVoided = IsVoided; UpdateLineOnRollingHandicap(market); }
public bool IsEquivalentTo(Market market, bool checkTags, bool checkSelections) { if (market == null) return false; if (market.Id != Id) return false; if(checkTags) { if (market.TagsCount != TagsCount) return false; if (market.TagKeys.Any(tag => !HasTag(tag) || GetTagValue(tag) != market.GetTagValue(tag))) return false; } if (checkSelections) { if (Selections.Count() != market.Selections.Count()) return false; foreach (var seln in market.Selections) { ISelectionState seln_state = this[seln.Id]; if (seln_state == null) return false; if (!seln_state.IsEquivalentTo(seln, checkTags)) return false; } } var result = IsSuspended == market.IsSuspended && IsActive == market.IsActive && IsResulted == market.IsResulted && IsPending == market.IsPending && IsVoided == market.IsVoided; if (IsRollingMarket) result &= Line == ((RollingMarket)market).Line; // the only case we really should pay attention // is when we have forced the suspension // when the market was active if(IsForcedSuspended) result &= market.IsSuspended; return result; }
public void UnsuspendFixtureAndMarketsTest() { // STEP 1: prepare stub data Mock<IResourceFacade> resource = new Mock<IResourceFacade>(); Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>(); Mock<IEventState> state = new Mock<IEventState>(); Mock<ISettings> settings = new Mock<ISettings>(); var provider = new StateManager(settings.Object, connector.Object); provider.SuspensionManager.RegisterAction(provider.SuspensionManager.SuspendInPlayMarketsStrategy, SuspensionReason.DISCONNECT_EVENT); // STEP 2: prepare the fixture data Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() }; fixture.Tags.Add("Sport", "Football"); // add at least one tags, so the MarketsRulesManager recognize it as a full-snapshot var mkt1 = new Market { Id = "MKT-1" }; mkt1.Selections.Add(new Selection { Id = "SELN", Status = SelectionStatus.Active, Tradable = true }); fixture.Markets.Add(mkt1); var mkt = new Market("MKT-2"); mkt.AddOrUpdateTagValue("traded_in_play", "false"); fixture.Markets.Add(mkt); resource.Setup(x => x.Id).Returns("ABC"); resource.Setup(x => x.Content).Returns(new Summary() { Sequence = 1 } ); resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty); resource.Setup(x => x.StopStreaming()).Raises(x => x.StreamDisconnected += null, EventArgs.Empty); resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)); // STEP 4: start the listener StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, settings.Object); listener.Start(); listener.IsStreaming.Should().BeTrue(); connector.Verify(x => x.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never); listener.Dispose(); //Should suspend at the fixture level only connector.Verify(x=> x.Suspend(It.Is<string>(fId => fId == "ABC")),Times.Once); //recreate listener //must have state setup otherwise it will process snapshot not unsuspend state.Setup(x => x.GetFixtureState(It.Is<string>(fId => fId == fixture.Id))) .Returns(new FixtureState() { Id = fixture.Id, MatchStatus = MatchStatus.InRunning, Sequence = fixture.Sequence }); listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, settings.Object); listener.Start(); // Unsuspend should be called on reconnect connector.Verify(x => x.UnSuspend(It.IsAny<Fixture>()),Times.Once); }
public void SuspensionManagerStrategiesTest() { var stateProvider = new Mock<IStateProvider>(); var plugin = new Mock<IAdapterPlugin>(); var suspensionManager = new SuspensionManager(stateProvider.Object, plugin.Object); var state = new MarketStateCollection("FXT-ID"); // STEP 1: prepare the fixture // 1) fixture is in running // 2) with 2 in play markets // 3) 1 not in-play market // 4) 3 markets with an unknown state Fixture fixture = new Fixture { Id = "FXT-ID", MatchStatus = MatchStatus.InRunning.ToString(), Sequence = 2 }; var mkt1 = new Market { Id = "MKT-1" }; mkt1.Selections.Add(new Selection { Id = "SELN", Status = SelectionStatus.Active }); var mkt2 = new Market { Id = "MKT-2" }; mkt2.Selections.Add(new Selection { Id = "SELN", Status = SelectionStatus.Active }); var mkt3 = new Market { Id = "MKT-3" }; mkt3.Selections.Add(new Selection { Id = "SELN", Status = SelectionStatus.Pending }); var mkt4 = new Market { Id = "MKT-4" }; mkt4.Selections.Add(new Selection { Id = "SELN", Status = SelectionStatus.Active }); mkt4.AddOrUpdateTagValue("traded_in_play", "false"); var mkt5 = new Market { Id = "MKT-5" }; mkt5.Selections.Add(new Selection { Id = "SELN", Status = SelectionStatus.Active }); mkt5.AddOrUpdateTagValue("traded_in_play", "true"); var mkt6 = new Market { Id = "MKT-6" }; mkt6.AddOrUpdateTagValue("traded_in_play", "true"); fixture.Markets.Add(mkt1); fixture.Markets.Add(mkt2); fixture.Markets.Add(mkt3); fixture.Markets.Add(mkt4); fixture.Markets.Add(mkt5); fixture.Markets.Add(mkt6); state.Update(fixture, true); state.CommitChanges(); // STEP 2: test the suspension strategies suspensionManager.SuspendAllMarketsStrategy(state); plugin.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture> ( y => y.Markets.Count == 6 && y.Markets.FirstOrDefault(z => z.Id == "MKT-1") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-2") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-3") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-4") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-5") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-6") != null ), It.IsAny<bool>())); suspensionManager.SuspendFixtureIfInPlayStrategy(state); plugin.Verify(x => x.Suspend(It.Is<string>(y => y == "FXT-ID"))); suspensionManager.SuspendFixtureStrategy(state); plugin.Verify(x => x.Suspend(It.Is<string>(y => y == "FXT-ID"))); suspensionManager.SuspendInPlayMarketsStrategy(state); // The SuspensionManager takes a conservative approach. // If the traded_in_play tag is not present, it assumes // that the market is a in-play market plugin.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture> ( y => y.Markets.Count == 3 && y.Markets.FirstOrDefault(z => z.Id == "MKT-1") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-2") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-3") == null && y.Markets.FirstOrDefault(z => z.Id == "MKT-4") == null && y.Markets.FirstOrDefault(z => z.Id == "MKT-5") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-6") == null ), It.IsAny<bool>())); // STEP 3: change the fixture // 1) change the fixture's match status // 2) remove a mkt // 3) add a new mkt fixture.MatchStatus = MatchStatus.MatchOver.ToString(); fixture.Markets.Remove(fixture.Markets.FirstOrDefault(x => x.Id == "MKT-5")); var mkt7 = new Market { Id = "MKT-7" }; mkt7.Selections.Add(new Selection { Id = "SELN", Status = SelectionStatus.Active }); mkt7.AddOrUpdateTagValue("traded_in_play", "true"); fixture.Markets.Add(mkt7); state.Update(fixture, true); state.CommitChanges(); // STEP 4: test the suspension strategies again suspensionManager.SuspendAllMarketsStrategy(state); // note that we must have 7 markets now because the // SuspensionManager looks at the MarketState, not // at the fixture plugin.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture> ( y => y.Markets.Count == 7 && y.Markets.FirstOrDefault(z => z.Id == "MKT-1") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-2") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-3") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-4") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-5") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-6") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-7") != null ), It.IsAny<bool>())); suspensionManager.SuspendFixtureIfInPlayStrategy(state); // The fixture is "MatchOver", so the Suspend() method should not have been called // Times.Exactly(2) because it has been called in the previous step...unfortunately // there seems to be no way to reset the verifications plugin.Verify(x => x.Suspend(It.Is<string>(y => y == "FXT-ID")), Times.Exactly(2)); suspensionManager.SuspendFixtureStrategy(state); plugin.Verify(x => x.Suspend(It.Is<string>(y => y == "FXT-ID")), Times.Exactly(3)); suspensionManager.SuspendInPlayMarketsStrategy(state); plugin.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture> ( y => y.Markets.Count == 4 && y.Markets.FirstOrDefault(z => z.Id == "MKT-1") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-2") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-3") == null && y.Markets.FirstOrDefault(z => z.Id == "MKT-4") == null && y.Markets.FirstOrDefault(z => z.Id == "MKT-5") != null && y.Markets.FirstOrDefault(z => z.Id == "MKT-6") == null && y.Markets.FirstOrDefault(z => z.Id == "MKT-7") != null ), It.IsAny<bool>())); }
public void MarkFixtureAsUnpublishedTest() { // STEP 1: prepare the stub data Mock<IResourceFacade> resource = new Mock<IResourceFacade>(); Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>(); Mock<IEventState> state = new Mock<IEventState>(); _settings.Setup(x => x.DeltaRuleEnabled).Returns(true); var provider = new StateManager(_settings.Object, connector.Object); //var suspended = false; //Action<IMarketStateCollection> suspension_strategy = x => {suspended = true;}; //suspension.RegisterAction(suspension_strategy, SuspensionReason.FIXTURE_DELETED); // Please note Sequence = 1 Fixture fixture = new Fixture { Id = "ABCDE", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = 1 }; Market mkt = new Market { Id = "MKT" }; fixture.Markets.Add(mkt); // ...and Sequence = 3 Fixture update = new Fixture { Id = "ABCDE", Sequence = 2, MatchStatus = ((int)MatchStatus.MatchOver).ToString(), Epoch = 2, LastEpochChangeReason = new [] {(int)EpochChangeReason.Deleted} }; StreamMessage message = new StreamMessage { Content = update }; resource.Setup(x => x.Id).Returns("ABCDE"); resource.Setup(x => x.Content).Returns(new Summary()); resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty); resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)); // STEP 2: start the listener StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object); listener.Start(); listener.IsStreaming.Should().BeTrue(); // STEP 3: let create at lea listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message))); connector.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture>(y => y.Markets.All(k => k.IsSuspended)), It.IsAny<bool>())); update = new Fixture { Id = "ABCDE", Sequence = 3, MatchStatus = ((int)MatchStatus.MatchOver).ToString(), Epoch = 2 }; mkt = new Market {Id = "MKT"}; update.Markets.Add(mkt); update.Tags.Add("tag", "tag"); message = new StreamMessage { Content = update }; listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message))); // STEP 4: if the delta rule was executed, the market would have been removed fixture.Markets.FirstOrDefault(x => x.Id == "MKT").Should().NotBeNull(); }
public MarketState(Market market, bool fullSnapshot) : this(market.Id) { IsRollingMarket = market is RollingMarket; this.Update(market, fullSnapshot); }
public void MarkMarkedAsForcedSuspended() { Mock<IResourceFacade> resource = new Mock<IResourceFacade>(); Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>(); Mock<IEventState> state = new Mock<IEventState>(); _settings.Setup(x => x.DeltaRuleEnabled).Returns(true); var provider = new StateManager(_settings.Object, connector.Object); provider.SuspensionManager.RegisterAction(provider.SuspensionManager.SuspendAllMarketsStrategy, SuspensionReason.SUSPENSION); //var suspended = false; //Action<IMarketStateCollection> suspension_strategy = x => {suspended = true;}; //suspension.RegisterAction(suspension_strategy, SuspensionReason.FIXTURE_DELETED); // Please note Sequence = 1 Fixture fixture = new Fixture { Id = "ABCDE", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = 1 }; Market mkt = new Market { Id = "MKT" }; fixture.Markets.Add(mkt); // ...and Sequence = 3 Fixture update = new Fixture { Id = "ABCDE", Sequence = 2, MatchStatus = ((int)MatchStatus.MatchOver).ToString(), Epoch = 2, LastEpochChangeReason = new[] { (int)EpochChangeReason.BaseVariables } }; StreamMessage message = new StreamMessage { Content = update }; resource.Setup(x => x.Id).Returns("ABCDE"); resource.Setup(x => x.Content).Returns(new Summary()); resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty); resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)); // STEP 2: start the listener StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,_settings.Object); listener.Start(); listener.IsStreaming.Should().BeTrue(); //Update snapshot sequence fixture.Sequence = 2; resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)); // STEP 3: let create at lea listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message))); var fixtureState = provider.CreateNewMarketRuleManager("ABCDE").CurrentState; fixtureState.Markets.All(x => fixtureState[x].IsForcedSuspended).Should().BeFalse(); }
private void AddMarket(Fixture snapshot) { var selections = new List<Selection> { new Selection {Id = "Sel1", Status = "1", Price = 0.45, Name = "Sel 1", Tradable = false}, new Selection {Id = "Sel2", Status = "1", Price = 0.45, Name = "Sel 2", Tradable = false}, new Selection {Id = "Sel3", Status = "1", Price = 0.45, Name = "Sel 3", Tradable = false} }; var market = new Market("testMarketId"); market.Selections.AddRange(selections); snapshot.Markets.Add(market); }
private static Market CreateSettledMarket(IMarketState MarketState) { var market = new Market (MarketState.Id); if (MarketState.HasTag("line")) { market.AddOrUpdateTagValue("line", MarketState.GetTagValue("line")); } foreach (var seln in MarketState.Selections) market.Selections.Add(new Selection { Id = seln.Id, Status = SelectionStatus.Void, Price = 0 }); return market; }
public void SerializeModelTest() { Fixture fixture = new Fixture { FixtureName = "TEST-NAME", Epoch = 10, LastEpochChangeReason = new[] { 10, 20 }, Id = "TEST-ID", StartTime = new DateTime(2000, 01, 01), Sequence = 12, MatchStatus = "40" }; fixture.Tags.Add("TEST-TAG-1", "1"); fixture.Tags.Add("TEST-TAG-2", 2); fixture.GameState.Add("TEST-STATE-1", 1); fixture.GameState.Add("TEST-STATE-2", "2"); Participant p1 = new Participant { Id = 1, Name = "P1" }; p1.Tags.Add("TEST-TAG-1", "1"); p1.Tags.Add("TEST-TAG-2", 2); Participant p2 = new Participant { Id = 2, Name = "P2" }; fixture.Participants.Add(p1); fixture.Participants.Add(p2); Market mkt1 = new Market { Id = "MKT1" }; mkt1.AddOrUpdateTagValue("name", "MKT1"); Selection seln1 = new Selection { Id = "SELN1", Price = 2.0, Status = SelectionStatus.Active, Tradable = false }; seln1.AddOrUpdateTagValue("name", "seln1"); seln1.AddOrUpdateTagValue("displayed", "true"); Selection seln2 = new Selection { Id = "SELN2", Price = 3.0, Status = SelectionStatus.Pending, Tradable = true }; seln2.AddOrUpdateTagValue("name", "seln2"); seln2.AddOrUpdateTagValue("displayed", "false"); mkt1.Selections.Add(seln1); mkt1.Selections.Add(seln2); RollingMarket mkt2 = new RollingMarket { Id = "RMKT2", Line = 2.0 }; mkt2.AddOrUpdateTagValue("name", "RMKT2"); RollingSelection seln3 = new RollingSelection { Id = "SELN3", Price = 7.0, Status = SelectionStatus.Pending, Tradable = true, Line = 21 }; ((Market)mkt2).Selections.Add(seln3); Market test2 = mkt2; test2.Selections.Count.Should().Be(1); (test2.Selections.FirstOrDefault() is RollingSelection).Should().BeTrue(); Market mkt3 = new RollingMarket(); mkt3.Id = "RMKT3"; mkt3.AddOrUpdateTagValue("name", "RMKT3"); fixture.Markets.Add(mkt1); fixture.Markets.Add(mkt2); fixture.Markets.Add(mkt3); fixture.RollingMarkets.FirstOrDefault(x => x.Id == "MKT1").Should().BeNull(); fixture.RollingMarkets.FirstOrDefault(x => x.Id == "RMKT2").Should().NotBeNull(); fixture.RollingMarkets.FirstOrDefault(x => x.Id == "RMKT3").Should().NotBeNull(); fixture.StandardMarkets.FirstOrDefault(x => x.Id == "MKT1").Should().NotBeNull(); fixture.StandardMarkets.FirstOrDefault(x => x.Id == "RMKT2").Should().BeNull(); fixture.StandardMarkets.FirstOrDefault(x => x.Id == "RMKT3").Should().BeNull(); string value = FixtureJsonHelper.ToJson(fixture); using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(value))) { stream.Position = 0; string value2 = Encoding.UTF8.GetString(stream.ToArray()); value.Should().BeEquivalentTo(value2); fixture = FixtureJsonHelper.GetFromJson(value2); } fixture.RollingMarkets.Count().Should().Be(2); fixture.StandardMarkets.Count().Should().Be(1); fixture.Markets.Count().Should().Be(3); fixture.Tags.Count.Should().Be(2); fixture.GameState.Count().Should().Be(2); fixture.Participants.Count().Should().Be(2); fixture.Markets.FirstOrDefault(x => x.Id == "MKT1").Selections.Count.Should().Be(2); fixture.Markets.FirstOrDefault(x => x.Id == "RMKT2").Selections.Count.Should().Be(1); fixture.Markets.FirstOrDefault(x => x.Id == "RMKT3").Selections.Count.Should().Be(0); BinaryStoreProvider<Fixture> provider = new BinaryStoreProvider<Fixture>(".", "test-{0}.dat"); provider.SetObject("TEST", fixture); fixture = provider.GetObject("TEST"); fixture.RollingMarkets.Count().Should().Be(2); fixture.StandardMarkets.Count().Should().Be(1); fixture.Markets.Count().Should().Be(3); fixture.Tags.Count.Should().Be(2); fixture.GameState.Count().Should().Be(2); fixture.Participants.Count().Should().Be(2); fixture.Markets.FirstOrDefault(x => x.Id == "MKT1").Selections.Count.Should().Be(2); fixture.Markets.FirstOrDefault(x => x.Id == "RMKT2").Selections.Count.Should().Be(1); fixture.Markets.FirstOrDefault(x => x.Id == "RMKT3").Selections.Count.Should().Be(0); fixture = value.FromJson<Fixture>(); fixture.RollingMarkets.Count().Should().Be(2); fixture.StandardMarkets.Count().Should().Be(1); fixture.Markets.Count().Should().Be(3); fixture.Tags.Count.Should().Be(2); fixture.GameState.Count().Should().Be(2); fixture.Participants.Count().Should().Be(2); fixture.Markets.FirstOrDefault(x => x.Id == "MKT1").Selections.Count.Should().Be(2); fixture.Markets.FirstOrDefault(x => x.Id == "RMKT2").Selections.Count.Should().Be(1); fixture.Markets.FirstOrDefault(x => x.Id == "RMKT3").Selections.Count.Should().Be(0); }
public void EditMarket(Market market, MarketRuleEditIntent action) { if (market == null || _edited.ContainsKey(market) || action == null) return; _edited[market] = action; }
public void DoNotSuspendFixtureOnDisconeectIfDeletedTest() { // STEP 1: prepare stub data Mock<IResourceFacade> resource = new Mock<IResourceFacade>(); Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>(); Mock<IEventState> state = new Mock<IEventState>(); Mock<ISettings> settings = new Mock<ISettings>(); var provider = new StateManager(settings.Object, connector.Object); // STEP 3: prepare the fixture data Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() }; fixture.Tags.Add("Sport", "Football"); // add at least one tags, so the MarketsRulesManager recognize it as a full-snapshot fixture.Markets.Add(new Market("MKT-1")); var mkt = new Market("MKT-2"); mkt.AddOrUpdateTagValue("traded_in_play", "false"); fixture.Markets.Add(mkt); // ...and MatchStatus=MatchOver Fixture update = new Fixture { Id = "ABC", Sequence = 2, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = 2, LastEpochChangeReason = new[] {(int)EpochChangeReason.Deleted} }; StreamMessage message = new StreamMessage { Content = update }; resource.Setup(x => x.Id).Returns("ABC"); resource.Setup(x => x.Content).Returns(new Summary()); resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty); resource.Setup(x => x.StopStreaming()).Raises(x => x.StreamDisconnected += null, EventArgs.Empty); resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)); // STEP 4: start the listener StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, settings.Object); listener.Start(); listener.IsStreaming.Should().BeTrue(); // STEP 5: send the update listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message))); // STEP 6: check the result, note tha MKT-2 is not in-play connector.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture>(y => y.Id == "ABC" && y.Markets.Count == 0), It.IsAny<bool>())); }
public void SelectionResulStateTest() { Market mkt = new Market("123"); var seln = new Selection() { Id = "A1", Result = new Result() { StakeParticipants = 1, StakePlaces = 2, WinParticipants = 3, WinPlaces = 4 } }; mkt.Selections.Add(seln); Fixture fxt = new Fixture() { Id = "FXT", FixtureName = "TestSelectionResultTest", MatchStatus = "40", }; fxt.Markets.Add(mkt); MarketStateCollection collection = new MarketStateCollection("FXT"); collection.Update(fxt, true); var model = collection["123"]["A1"].Result as SelectionResultState; model.Should().NotBeNull(); model.IsEquivalentTo(seln.Result).Should().BeTrue(); var clone = model.Clone(); model.IsEqualTo(clone).Should().BeTrue(); seln.Result.WinParticipants = 2; model.IsEquivalentTo(seln.Result).Should().BeFalse(); }
public MarketRuleEditIntent GetEditingAction(Market market) { return _edited.ContainsKey(market) ? _edited[market] : null; }
public void GivenAFixtureWithTheFollowingMarkets(Table table) { ScenarioContext.Current.Clear(); Fixture fixture = new Fixture { Id = "Test", MatchStatus = "40" }; ScenarioContext.Current.Add("FIXTURE", fixture); foreach (var row in table.Rows) { Market mkt = new Market {Id = row["Market"]}; mkt.AddOrUpdateTagValue("name", row["Name"]); fixture.Markets.Add(mkt); if (table.ContainsColumn("Selections")) { int seln_count = Convert.ToInt32(row["Selections"]); for (int i = 0; i < seln_count; i++) { Selection seln = new Selection { Name = row["Name"] + (i + 1) }; seln.Id = seln.Name; mkt.Selections.Add(seln); } } } }
public MarketRuleAddIntent GetAddAction(Market mkt) { return _added[mkt]; }
private static Market CreateMarket(IMarketState marketState,bool isSuspended = true) { var market = new Market(marketState.Id) { IsSuspended = isSuspended }; foreach (var seln in marketState.Selections) market.Selections.Add(new Selection { Id = seln.Id, Status = SelectionStatus.Pending, Tradable = !isSuspended }); return market; }
public void DeltaRuleWithMarketSeverity() { // STEP 1: prepare stub data var settings = new Mock<ISettings>(); var plugin = new Mock<IAdapterPlugin>(); var stateprovider = new StateManager(settings.Object, plugin.Object); DeltaRule.Instance.Severity = DeltaRule.DeltaRuleSeverity.REMOVE_MARKETS; List<IMarketRule> rules = new List<IMarketRule> { DeltaRule.Instance }; // STEP 2: prepare fixture data // Fixture // - MKT1 // -- SELN_1_1 // -- SELN_1_2 // - MKT2 // -- SELN_2_1 // -- SELN_2_2 Fixture fixture = new Fixture { Id = "TestId", MatchStatus = "40" }; fixture.Tags.Add("Sport", "Football"); Market mkt = new Market { Id = "MKT1" }; mkt.AddOrUpdateTagValue("name", "mkt1"); mkt.AddOrUpdateTagValue("type", "type1"); Selection seln = new Selection { Id = "SELN_1_1" }; seln.AddOrUpdateTagValue("name", "seln_1_1"); seln.Tradable = true; seln.Status = SelectionStatus.Active; seln.Price = 0.1; mkt.Selections.Add(seln); seln = new Selection { Id = "SELN_1_2" }; seln.AddOrUpdateTagValue("name", "seln_1_2"); seln.Tradable = true; seln.Status = SelectionStatus.Active; seln.Price = 0.2; mkt.Selections.Add(seln); fixture.Markets.Add(mkt); mkt = new Market { Id = "MKT2" }; mkt.AddOrUpdateTagValue("name", "mkt2"); mkt.AddOrUpdateTagValue("type", "type2"); seln = new Selection { Id = "SELN_2_1" }; seln.AddOrUpdateTagValue("name", "seln_2_1"); seln.Tradable = false; seln.Status = SelectionStatus.Pending; seln.Price = null; mkt.Selections.Add(seln); seln = new Selection { Id = "SELN_2_2" }; seln.AddOrUpdateTagValue("name", "seln_2_2"); seln.Tradable = false; seln.Status = SelectionStatus.Pending; seln.Price = null; mkt.Selections.Add(seln); fixture.Markets.Add(mkt); // STEP 3: invoke the delta rule MarketRulesManager manager = new MarketRulesManager(fixture.Id, stateprovider, rules); manager.ApplyRules(fixture); // this will not have any effect as we don't have any state yet manager.CommitChanges(); manager.ApplyRules(fixture); // here is where the delta rule is invoked (note that we haven't changed anything on the fixture) manager.CommitChanges(); // STEP 4: check the results (delta rule should have removed everything) fixture.Markets.Count.Should().Be(0); // STEP 5: change a single field seln.Price = 1.2; fixture.Markets.Add(mkt); mkt.Selections.Count().Should().Be(2); // STEP 6: apply the delta rule again manager.ApplyRules(fixture); // STEP 7: the market should not have been filtered out fixture.Markets.Count().Should().Be(1); fixture.Markets[0].Selections.Count().Should().Be(2); }