private void SetUpSnapshotAndMarkets(MatchStatus status = MatchStatus.InRunning) { _snapshot = new Fixture {Id = "123", MatchStatus = ((int) status).ToString()}; _snapshot.Tags.Add("Sport", "TestFootball"); _market1 = new Mock<Market>(); _market2 = new Mock<Market>(); _market3 = new Mock<Market>(); // Initial Active Market _market1.SetupAllProperties(); _market1.Setup(m => m.Selections).Returns(GetSelections(true, false)); _market1.Object.Id = "One"; _market1.Object.AddOrUpdateTagValue("name", "One"); // Initial Inactive (pending) Market _market2.SetupAllProperties(); _market2.Setup(m => m.Selections).Returns(GetSelections(false, false)); _market2.Object.Id = "Two"; _market2.Object.AddOrUpdateTagValue("name", "Two"); // Initial Active Market _market3.SetupAllProperties(); _market3.Setup(m => m.Selections).Returns(GetSelections(true, false)); _market3.Object.Id = "Three"; _market3.Object.AddOrUpdateTagValue("name", "Three"); _snapshot.Markets.Add(_market1.Object); _snapshot.Markets.Add(_market2.Object); _snapshot.Markets.Add(_market3.Object); }
public void ShouldStartAndStopListening() { var fixtureSnapshot = new Fixture { Id = "TestId", MatchStatus = "30", Sequence = 1 }; var plugin = new Mock<IAdapterPlugin>(); var resource = new Mock<IResourceFacade>(); var connector = new Mock<IAdapterPlugin>(); var eventState = new Mock<IEventState>(); var marketFilterObjectStore = new StateManager(_settings.Object,plugin.Object); resource.Setup(r => r.Sport).Returns("Football"); resource.Setup(r => r.Content).Returns(new Summary()); resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty); resource.Setup(r => r.StopStreaming()).Raises(r => r.StreamDisconnected += null, EventArgs.Empty); resource.Setup(r => r.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixtureSnapshot)); resource.Setup(r => r.Id).Returns("TestId"); eventState.Setup(e => e.GetCurrentSequence(It.IsAny<string>(), It.IsAny<string>())).Returns(-1); var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore,_settings.Object); listener.MonitorEvents(); listener.Start(); listener.Stop(); listener.ShouldRaise("OnConnected"); listener.ShouldNotRaise("OnError"); listener.ShouldRaise("OnStop"); listener.ShouldNotRaise("OnDisconnected","The disconnection is triggered by the user"); connector.Verify(c => c.ProcessSnapshot(It.IsAny<Fixture>(), false), Times.Once()); }
public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState) { var result = new MarketRuleResultIntent(); if (oldState == null) return result; var deletedMarkets = newState.Markets.Select(marketId => newState[marketId]) .Where(marketState => marketState.IsDeleted && oldState.HasMarket(marketState.Id) && !oldState[marketState.Id].IsDeleted) .ToList(); var newDeletedMarketState = deletedMarkets.Select(CreateSuspendedMarket).ToList(); if (deletedMarkets.Any()) { newDeletedMarketState.ForEach(m => { _logger.DebugFormat("market rule={0} => {1} of fixtureId={2} was deleted from UDAPI - it will be suspended", Name, m, fixture.Id); result.AddMarket(m, new MarketRuleAddIntent(MarketRuleAddIntent.OperationType.CHANGE_SELECTIONS)); }); } return result; }
public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState) { MarketRuleResultIntent intent = new MarketRuleResultIntent(); // only apply delta rule on a full snapshot if (fixture.Tags == null || !fixture.Tags.Any() || oldState == null) return intent; foreach (var mkt in fixture.Markets) { if (oldState.HasMarket(mkt.Id)) { IMarketState state = oldState[mkt.Id]; // do not apply the delta rule on markets which have // been put in a forced suspended state if (state.IsForcedSuspended) continue; if (Severity == DeltaRuleSeverity.REMOVE_SELECTIONS) { ApplyDeltaRule_RemovingSelections(fixture, mkt, state, intent); } else if (Severity == DeltaRuleSeverity.REMOVE_MARKETS) { ApplyDeltaRule_RemovingMarkets(fixture, mkt, state, intent); } } } return intent; }
public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState) { var result = new MarketRuleResultIntent(); if (!fixture.IsMatchOver || oldState == null) return result; var markets = fixture.Markets.ToDictionary(m => m.Id); // get list of markets which are either no longer in snapshot or are in the snapshot and are not resulted // markets which were already priced (activated) should be ignored var marketsNotPresentInTheSnapshot = new List<IMarketState>(); foreach (var mkt in newState.Markets) { IMarketState mkt_state = newState[mkt]; if (!mkt_state.IsResulted && (!markets.ContainsKey(mkt_state.Id) || !markets[mkt_state.Id].IsResulted)) marketsNotPresentInTheSnapshot.Add(mkt_state); } foreach (var mkt_state in marketsNotPresentInTheSnapshot) { if (mkt_state.HasBeenActive) { _logger.DebugFormat("market rule={0} => marketId={1} of {2} was priced during the fixture lifetime but has NOT been settled on match over.", Name, mkt_state.Id, fixture); continue; } if (!mkt_state.HasBeenProcessed) { _logger.DebugFormat("market rule={0} => marketId={1} of {2} was never passed to the plugin.", Name, mkt_state.Id, fixture); continue; } var market = fixture.Markets.FirstOrDefault(m => m.Id == mkt_state.Id); if (market == null) { _logger.DebugFormat("market rule={0} => marketId={1} of {2} is marked to be voided", Name, mkt_state.Id, fixture); result.AddMarket(CreateSettledMarket(mkt_state), new MarketRuleAddIntent(MarketRuleAddIntent.OperationType.SETTLE_SELECTIONS)); } else { _logger.DebugFormat("market rule={0} => marketId={1} of {2} that was in the snapshot but wasn't resulted is marked to be voided", Name, market.Id, fixture); Action<Market> action = x => x.Selections.ForEach(s => s.Status = SelectionStatus.Void); MarketRuleEditIntent edit = new MarketRuleEditIntent(action, MarketRuleEditIntent.OperationType.CHANGE_SELECTIONS); result.EditMarket(market, edit); } } return result; }
public void CreateFixture() { _fixture = new Fixture() { Id = "TestFixtureId", FixtureName = "Testing fixture gamestate" }; _fixture.GameState.Clear(); }
/// <summary> /// /// Remove markets from snapshot/update when: /// current market state is inactive AND the previous state was inactive too (with no change in status or name) /// /// NB: If there is a change in market's name or status then will not be removed /// /// </summary> public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState) { var result = new MarketRuleResultIntent(); var inactiveMarkets = fixture.Markets.Where( m => (oldState != null && oldState.HasMarket(m.Id) && oldState[m.Id].IsEqualTo(newState[m.Id])) && (!m.IsActive && !oldState[m.Id].IsActive)); foreach (var market in inactiveMarkets.ToList()) { result.MarkAsRemovable(market); _Logger.DebugFormat("market rule={0} => {1} of fixtureId={2} is marked as removable", Name, market, fixture.Id); } return result; }
public void Update(Fixture fixture, bool fullSnapshot) { FixtureSequence = fixture.Sequence; FixtureName = fixture.FixtureName; FixtureStatus = (MatchStatus) Enum.Parse(typeof (MatchStatus), fixture.MatchStatus); if (fullSnapshot) { if(fixture.Tags.ContainsKey("Sport")) Sport = fixture.Tags["Sport"].ToString(); var marketsLookUp = fixture.Markets.ToDictionary(m => m.Id); //if market doesn't exist in the snapshot the definition must have been changed Markets.Where(marketId => !marketsLookUp.ContainsKey(marketId)).ForEach(marketId => this[marketId].IsDeleted = true); } _processed = new Dictionary<string, IUpdatableMarketState>(); foreach (var market in fixture.Markets) { IUpdatableMarketState mkt_state = null; if (HasMarket(market.Id)) { mkt_state = this[market.Id] as IUpdatableMarketState; mkt_state.Update(market, fullSnapshot); } else { mkt_state = new MarketState(market, fullSnapshot); ((MarketState)mkt_state).Index = _States.Count; this[market.Id] = mkt_state; } _processed.Add(market.Id, mkt_state); } }
public void ProcessFixtureDeletion(Fixture fixture) { _Logger.InfoFormat("Request for delete {0} received", fixture); }
public void ProcessStreamUpdate(Fixture fixture, bool hasEpochChanged = false) { _Logger.InfoFormat("Received delta snapshot for {0} (hasEpochChanged={1}), written to queue at: {2}", fixture, hasEpochChanged,fixture.TimeStamp); }
private static Fixture GetFixtureWithSuspendedMarkets(IMarketStateCollection state, out IEnumerable<IMarketState> includedMarketStates) { includedMarketStates = new List<IMarketState>(); var fixture = new Fixture { Id = state.FixtureId, MatchStatus = ((int) state.FixtureStatus).ToString(), Sequence = state.FixtureSequence }; foreach (var mkt_id in state.Markets) { ((List<IMarketState>)includedMarketStates).Add(state[mkt_id]); fixture.Markets.Add(CreateMarket(state[mkt_id])); } return fixture; }
private void BuildDefaultStrategies() { DoNothingStrategy = x => { }; SuspendFixtureStrategy = x => _plugin.Suspend(x.FixtureId); SuspendFixtureIfInPlayStrategy = x => { if (x.FixtureStatus == MatchStatus.InRunning) _plugin.Suspend(x.FixtureId); }; SuspendAllMarketsStrategy = x => { IEnumerable<IMarketState> includedMarketStates; var fixture = GetFixtureWithSuspendedMarkets(x, out includedMarketStates); _logger.DebugFormat("Sending suspension command through the plugin for fixtureId={0}", x.FixtureId); _plugin.ProcessStreamUpdate(fixture); _logger.InfoFormat("Marking markets for fixtureId={0} as suspended", x.FixtureId); ((IUpdatableMarketStateCollection)x).OnMarketsForcedSuspension(includedMarketStates); }; SuspendAllMarketsAndSetMatchStatusDeleted = x => { IEnumerable<IMarketState> includedMarketStates; var fixture = GetFixtureWithSuspendedMarkets(x, out includedMarketStates); fixture.MatchStatus = ((int)MatchStatus.Deleted).ToString(); _logger.DebugFormat("Sending suspension command through the plugin for fixtureId={0} and setting its MatchStatus as deleted", x.FixtureId); _plugin.ProcessStreamUpdate(fixture); _logger.InfoFormat("Marking markets for fixtureId={0} as suspended", x.FixtureId); ((IUpdatableMarketStateCollection)x).OnMarketsForcedSuspension(includedMarketStates); }; SuspendFixtureAndSetMatchStatusDeleted = x => { var fixture = new Fixture { Id = x.FixtureId, MatchStatus = ((int)MatchStatus.Deleted).ToString(), Sequence = x.FixtureSequence }; _logger.DebugFormat("Sending suspension command through the plugin for fixtureId={0} and setting its MatchStatus as deleted", x.FixtureId); _plugin.ProcessStreamUpdate(fixture); _logger.InfoFormat("Marking markets for fixtureId={0} as suspended", x.FixtureId); }; SuspendInPlayMarketsStrategy = x => { List<IMarketState> includedMarketStates = new List<IMarketState>(); var fixture = new Fixture { Id = x.FixtureId, MatchStatus = ((int)x.FixtureStatus).ToString(), Sequence = x.FixtureSequence }; foreach (var mkt_id in x.Markets) { // we take a conservative approach here. // If, for any reason, the traded_in_play // is not present, we assume it is. Better // to suspend more markets, than less IMarketState state = x[mkt_id]; if (state.HasTag("traded_in_play") && string.Equals(state.GetTagValue("traded_in_play"), "false", StringComparison.OrdinalIgnoreCase)) { _logger.DebugFormat("marketId={0} of fixtureId={1} will not be suspended as it is not traded in play", mkt_id, fixture.Id); continue; } if (!state.HasBeenActive) { _logger.DebugFormat("marketId={0} of fixtureId={1} will not be suspended as it has not been active before", mkt_id, fixture.Id); continue; } includedMarketStates.Add(state); fixture.Markets.Add(CreateMarket(x[mkt_id])); } _logger.DebugFormat("Sending suspension command through the plugin for in-play markets of fixtureId={0}", x.FixtureId); _plugin.ProcessStreamUpdate(fixture); _logger.InfoFormat("Marking markets for fixtureId={0} as suspended", x.FixtureId); ((IUpdatableMarketStateCollection)x).OnMarketsForcedSuspension(includedMarketStates); }; }
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 GetFixtureOverviewAfterStreamUpdatesTest() { var fixtureOneId = "fixtureOne"; _resource.Setup(x => x.Id).Returns(fixtureOneId); _resource.Setup(x => x.Content).Returns(new Summary()); _resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); _resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(GetSnapshotWithMarkets(fixtureOneId))); _resource.Setup(x => x.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty); var deltas = new List<IFixtureOverviewDelta>(); var subscriber = _supervisor.GetFixtureOverviewStream().ObserveOn(NewThreadScheduler.Default).Subscribe(deltas.Add); _supervisor.CreateStreamListener(_resource.Object, _plugin.Object); var fixtureOverviews = _supervisor.GetFixtures(); fixtureOverviews.Should().NotBeNullOrEmpty(); fixtureOverviews.Should().Contain(f => f.Id == fixtureOneId); _supervisor.StartStreaming(fixtureOneId); var epoch = 1; var streamUpdate = new Fixture { Id = fixtureOneId, Sequence = 2, Epoch = epoch, MatchStatus = ((int)MatchStatus.InRunning).ToString() }; SendStreamUpdate(streamUpdate); Thread.Sleep(1000); deltas.Should().NotBeEmpty(); var sequenceTwoDeltas = deltas.Where(d => d.FeedUpdate != null && d.FeedUpdate.Sequence == 2).ToList(); sequenceTwoDeltas.Should().NotBeNull(); sequenceTwoDeltas.Count.Should().Be(2); //FeedUpdate with IsProcessed in both states exists sequenceTwoDeltas.Any(d => d.FeedUpdate.IsProcessed).Should().BeTrue(); sequenceTwoDeltas.Any(d => !d.FeedUpdate.IsProcessed).Should().BeTrue(); var fixtureOverview = _supervisor.GetFixtureOverview(fixtureOneId); fixtureOverview.GetFeedAudit().Count(f => f.Sequence == 2).Should().Be(1); subscriber.Dispose(); }
private void ProcessSnapshot(Fixture snapshot, bool isFullSnapshot, bool hasEpochChanged, bool setErrorState = true, bool skipMarketRules = false) { var logString = isFullSnapshot ? "snapshot" : "stream update"; if (snapshot == null || (snapshot != null && string.IsNullOrWhiteSpace(snapshot.Id))) throw new ArgumentException(string.Format("Received empty {0} for {1}", logString, _resource)); _logger.InfoFormat("Processing {0} for {1}", logString, snapshot); Stopwatch timer = new Stopwatch(); timer.Start(); try { if (isFullSnapshot && !VerifySequenceOnSnapshot(snapshot)) return; if (IsDisposing || IsStopping) { _logger.WarnFormat("Shutting down stream listener, the snapshot {0} won't be processed.", snapshot); return; } bool is_inplay = string.Equals(snapshot.MatchStatus, ((int)MatchStatus.InRunning).ToString(), StringComparison.OrdinalIgnoreCase); IsInPlay = is_inplay; if (!skipMarketRules) { _marketsRuleManager.ApplyRules(snapshot); snapshot.IsModified = true; } else { _marketsRuleManager.ApplyRules(snapshot,isRemovalDisabled : true); } if (isFullSnapshot) _platformConnector.ProcessSnapshot(snapshot, hasEpochChanged); else _platformConnector.ProcessStreamUpdate(snapshot, hasEpochChanged); UpdateState(snapshot, isFullSnapshot); IsErrored = false; } catch (FixtureIgnoredException ex) { _logger.WarnFormat("{0} received a FixtureIgnoredException", _resource); IsIgnored = true; _Stats.IncrementValue(AdapterCoreKeys.ERROR_COUNTER); RaiseEvent(OnError, ex); } catch (AggregateException ex) { _marketsRuleManager.RollbackChanges(); int total = ex.InnerExceptions.Count; int count = 0; foreach (var e in ex.InnerExceptions) { _logger.Error(string.Format("Error processing {0} for {1} ({2}/{3})", logString, snapshot, ++count, total), e); } _Stats.IncrementValue(AdapterCoreKeys.ERROR_COUNTER); RaiseEvent(OnError, ex); if (setErrorState) SetErrorState(); else throw; } catch (Exception ex) { _marketsRuleManager.RollbackChanges(); _Stats.IncrementValue(AdapterCoreKeys.ERROR_COUNTER); _logger.Error(string.Format("Error processing {0} {1}", logString, snapshot), ex); RaiseEvent(OnError, ex); if (setErrorState) SetErrorState(); else throw; } finally { timer.Stop(); if (isFullSnapshot) _Stats.AddValue(AdapterCoreKeys.SNAPSHOT_PROCESSING_TIME, timer.ElapsedMilliseconds.ToString()); else _Stats.AddValue(AdapterCoreKeys.UPDATE_PROCESSING_TIME, timer.ElapsedMilliseconds.ToString()); } _logger.InfoFormat("Finished processing {0} for {1}", logString, snapshot); }
public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState) { var result = new MarketRuleResultIntent(); if (_includedSports.Contains(newState.Sport.ToLower())) { foreach (var mkt in fixture.Markets) { string type = string.Format("{0}.{1}", newState.Sport, mkt.Type).ToLower(); if (_excludedMarketTypes.Contains(type)) { _Logger.DebugFormat("market rule={0} => {1} of {2} is excluded from rule due its type={3}", Name, mkt, fixture, mkt.Type); continue; } var oldMarketState = oldState != null ? oldState[mkt.Id] : null; var newMarketState = newState[mkt.Id]; if (oldMarketState == null) { //must be a snapshot then if (newMarketState.IsActive) { //create market _Logger.DebugFormat("market rule={0} => {1} of {2} is created", Name, mkt, fixture); result.MarkAsUnRemovable(mkt); } else { //dont create market _Logger.DebugFormat("market rule={0} => {1} of {2} is not created", Name, mkt, fixture); result.MarkAsRemovable(mkt); } } else { if (oldMarketState.HasBeenActive) continue; if (newMarketState.IsActive) { //create Action<Market> editMarketAction = (m => { if (newMarketState.TagsCount == 0) return; foreach (var tagKey in newMarketState.TagKeys) { m.AddOrUpdateTagValue(tagKey, newMarketState.GetTagValue(tagKey)); } foreach (var sel in m.Selections) { var selState = newMarketState[sel.Id]; foreach (var tagKey in selState.TagKeys) { sel.AddOrUpdateTagValue(tagKey, selState.GetTagValue(tagKey)); } } }); var mri = new MarketRuleEditIntent(editMarketAction, MarketRuleEditIntent.OperationType.CHANGE_DATA); _Logger.DebugFormat("market rule={0} => {1} of {2} is created", Name, mkt, fixture); result.EditMarket(mkt, mri); } else { //dont create market _Logger.DebugFormat("market rule={0} => {1} of {2} is not created", Name, mkt, fixture); result.MarkAsRemovable(mkt); } } } } return result; }
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 void GetDeltaErrorsTest() { var fixtureOneId = "fixtureOne"; var resourceOne = new Mock<IResourceFacade>(); resourceOne.Setup(x => x.Id).Returns(fixtureOneId); resourceOne.Setup(x => x.Content).Returns(new Summary()); resourceOne.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); resourceOne.Setup(x => x.Sport).Returns("Football"); resourceOne.SetupSequence(x => x.GetSnapshot()) .Returns(FixtureJsonHelper.ToJson(GetSnapshotWithMarkets(fixtureOneId))) .Returns(String.Empty) .Returns(FixtureJsonHelper.ToJson(GetSnapshotWithMarkets(fixtureOneId, 10, 3))); resourceOne.Setup(x => x.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty); _supervisor.CreateStreamListener(resourceOne.Object, _plugin.Object); var fixtureOverviews = _supervisor.GetFixtures(); fixtureOverviews.Should().NotBeNullOrEmpty(); fixtureOverviews.Should().Contain(f => f.Id == fixtureOneId); _supervisor.StartStreaming(fixtureOneId); var streamUpdate = new Fixture { Id = fixtureOneId, Sequence = 2, //Epoch increased Epoch = 10, MatchStatus = ((int)MatchStatus.InRunning).ToString() }; var deltas = new List<IFixtureOverviewDelta>(); using (var subscriber = _supervisor.GetFixtureOverviewStream().Subscribe(deltas.Add)) { //in order to generate error the resource is setup to return empty snapshot //the snapshot should be taken because epoch is changed SendStreamUpdate(streamUpdate); deltas.Should().NotBeEmpty(); deltas.FirstOrDefault(d => d.LastError != null).Should().NotBeNull(); //error was resolved with a further snapshot deltas.FirstOrDefault(d => d.LastError != null && !d.LastError.IsErrored).Should().NotBeNull(); } }
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 void CheckUpdatesAreTrackedTest() { var fixtureOneId = "fixtureOne"; var resourceOne = new Mock<IResourceFacade>(); resourceOne.Setup(x => x.Id).Returns(fixtureOneId); resourceOne.Setup(x => x.Content).Returns(new Summary()); resourceOne.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); resourceOne.SetupSequence(x => x.GetSnapshot()) .Returns(FixtureJsonHelper.ToJson(GetSnapshotWithMarkets(fixtureOneId))) .Returns(FixtureJsonHelper.ToJson(GetSnapshotWithMarkets(fixtureOneId, 10, 3))); resourceOne.Setup(x => x.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty); _supervisor.CreateStreamListener(resourceOne.Object, _plugin.Object); var fixtureOverviews = _supervisor.GetFixtures(); fixtureOverviews.Should().NotBeNullOrEmpty(); fixtureOverviews.Should().Contain(f => f.Id == fixtureOneId); _supervisor.StartStreaming(fixtureOneId); var streamUpdate = new Fixture { Id = fixtureOneId, Sequence = 2, //Epoch increased Epoch = 10, MatchStatus = ((int)MatchStatus.InRunning).ToString() }; Enumerable.Range(3, 13).ForEach(s => { streamUpdate.Sequence = s; SendStreamUpdate(streamUpdate); }); var fixtureOverview = _supervisor.GetFixtureOverview(fixtureOneId); fixtureOverview.GetFeedAudit().Should().NotBeEmpty(); fixtureOverview.GetFeedAudit().FirstOrDefault(f => f.Sequence == 12 && f.IsProcessed).Should().NotBeNull(); fixtureOverview.FeedUpdate.Sequence.Should().BeGreaterThan(10); }
private Fixture GetUnsuspendedFixture(IMarketStateCollection state,out List<IMarketState> marketStates) { marketStates = new List<IMarketState>(); var fixture = new Fixture { Id = state.FixtureId, MatchStatus = ((int)state.FixtureStatus).ToString(), Sequence = state.FixtureSequence }; foreach (var mkt_id in state.Markets) { var marketState = state[mkt_id]; if(marketState == null) continue; marketStates.Add(marketState); //only unsuspend market if it's suspended by Adapter and not suspended in the feed if (marketState.IsForcedSuspended && !marketState.IsSuspended) { fixture.Markets.Add(CreateMarket(state[mkt_id], false)); } } return fixture; }
public void CheckErrorsAreTrackedTest() { var fixtureOneId = "fixtureOne"; _resource.Setup(x => x.Id).Returns(fixtureOneId); _resource.Setup(x => x.Content).Returns(new Summary()); _resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning); _resource.SetupSequence(x => x.GetSnapshot()) .Returns(FixtureJsonHelper.ToJson(GetSnapshotWithMarkets(fixtureOneId))) .Returns(String.Empty) .Returns(String.Empty) .Returns(String.Empty) .Returns(String.Empty) .Returns(FixtureJsonHelper.ToJson(GetSnapshotWithMarkets(fixtureOneId, 10, 15))); _resource.Setup(x => x.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty); _supervisor.CreateStreamListener(_resource.Object, _plugin.Object); var fixtureOverviews = _supervisor.GetFixtures(); fixtureOverviews.Should().NotBeNullOrEmpty(); fixtureOverviews.Should().Contain(f => f.Id == fixtureOneId); _supervisor.StartStreaming(fixtureOneId); var streamUpdate = new Fixture { Id = fixtureOneId, Sequence = 2, //Epoch increased Epoch = 10, MatchStatus = ((int)MatchStatus.InRunning).ToString() }; var deltas = new List<IFixtureOverviewDelta>(); using (var subscriber = _supervisor.GetFixtureOverviewStream().Subscribe(deltas.Add)) { Enumerable.Range(3, 10).ForEach(s => { streamUpdate.Sequence = s; SendStreamUpdate(streamUpdate); }); } var fixtureOverview = _supervisor.GetFixtureOverview(fixtureOneId); fixtureOverview.GetErrorsAudit().Should().NotBeEmpty(); var errorsAudit = fixtureOverview.GetErrorsAudit(); //at least 4 failed snapshots errorsAudit.Count().Should().Be(4); //the final snapshot sholud have succeeded fixtureOverview.LastError.IsErrored.Should().BeFalse(); //there should be delta notification with LastError update IsErrored = false deltas.FirstOrDefault(d=> d.LastError != null && d.LastError.ResolvedAt == fixtureOverview.LastError.ResolvedAt && d.LastError.Sequence == fixtureOverview.LastError.Sequence).Should().NotBeNull(); }
public void ProcessSnapshot(Fixture fixture, bool hasEpochChanged = false) { _Logger.InfoFormat("Received snapshot for {0} (hasEpochChanged={1})", fixture, hasEpochChanged); }
private void SendStreamUpdate(Fixture streamUpdate) { var listener = _supervisor.GetType() .InvokeMember("GetStreamListener" , BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, _supervisor, new object[] { streamUpdate.Id }) as StreamListener; var message = new StreamMessage { Content = streamUpdate }; listener.ResourceOnStreamEvent(null, new StreamEventArgs(JsonConvert.SerializeObject(message))); }
public void ProcessMatchStatus(Fixture fixture) { _Logger.InfoFormat("Request for processing Match Statuf of {0} received", fixture); }
private Fixture GetSnapshotWithMarkets(string id, int epoch = 1, int sequence = 1) { var snapshot = new Fixture { Id = id, Sequence = sequence, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = epoch }; AddMarket(snapshot); AddTags(snapshot); return snapshot; }
public void UnSuspend(Fixture fixture) { _Logger.InfoFormat("Request for un-suspend {0} received", fixture); }
private void AddTags(Fixture snapshot) { snapshot.Tags.Add("SSLNCompetitionId","TestCompId"); snapshot.Tags.Add("SSLNCompetitionName", "Test Competition Name"); }
public void ApplyPostRulesProcessing(Fixture fixture) { foreach(var mkt in fixture.Markets) { IUpdatableMarketState tmp = null; if(_processed.TryGetValue(mkt.Id, out tmp)) { tmp.ApplyPostRulesProcessing(); } } }
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); }