public void WhenStreamingAndMatchOverUpdateAfterSecondTimeMissingSequencesThenRecreateStreamListenerAndProcessMatchOver() { // //Arrange // Fixture snapshot; Mock <IResourceFacade> resourceFacadeMock; SetupCommonMockObjects( /*sport*/ FootabllSportMock.Object.Name, /*fixtureData*/ FixtureSamples.football_inplay_snapshot_2, /*storedData*/ new { Epoch = 3, Sequence = 1, MatchStatus = MatchStatus.InRunning }, out snapshot, out resourceFacadeMock); ServiceMock.Setup(o => o.GetResources(It.Is <string>(s => s.Equals(FootabllSportMock.Object.Name)))) .Returns(new List <IResourceFacade> { resourceFacadeMock.Object }); StreamHealthCheckValidationMock.Setup(a => a.CanConnectToStreamServer( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>())) .Returns(true); FixtureValidationMock.Setup(a => a.IsSnapshotNeeded( It.IsAny <IResourceFacade>(), It.IsAny <FixtureState>())) .Returns(true); // //Act // var streamListenerManagerActor = ActorOfAsTestActorRef <StreamListenerManagerActor>( Props.Create(() => new StreamListenerManagerActor( SettingsMock.Object, PluginMock.Object, StateManagerMock.Object, SuspensionManagerMock.Object, StreamHealthCheckValidationMock.Object, FixtureValidationMock.Object)), StreamListenerManagerActor.ActorName); var sportProcessorRouterActor = ActorOfAsTestActorRef <SportProcessorRouterActor>( Props.Create(() => new SportProcessorRouterActor(ServiceMock.Object)) .WithRouter(new SmallestMailboxPool(SettingsMock.Object.FixtureCreationConcurrency)), SportProcessorRouterActor.ActorName); sportProcessorRouterActor.Tell(new ProcessSportMsg { Sport = FootabllSportMock.Object.Name }); IActorRef streamListenerActorRef; StreamListenerActor streamListenerActor = null; IActorRef resourceActorRef; IActorRef healthCheckActorRef; // //Assert // #region 1st processing //first time the stream listeners goes into Streaming State AwaitAssert(() => { streamListenerActorRef = GetChildActorRef( streamListenerManagerActor, StreamListenerActor.GetName(resourceFacadeMock.Object.Id)); streamListenerActor = GetUnderlyingActor <StreamListenerActor>(streamListenerActorRef); resourceActorRef = GetChildActorRef(streamListenerActorRef, ResourceActor.ActorName); healthCheckActorRef = GetChildActorRef(streamListenerActorRef, StreamHealthCheckActor.ActorName); Assert.NotNull(streamListenerActorRef); Assert.NotNull(streamListenerActor); Assert.NotNull(resourceActorRef); Assert.NotNull(healthCheckActorRef); Assert.AreEqual(StreamListenerState.Streaming, streamListenerActor.State); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); #endregion #region 2nd processing //second time the stream is not valid because of missing sequences and the fixture is suspended and snapshot processed StreamHealthCheckValidationMock.Reset(); StreamHealthCheckValidationMock.Setup(a => a.CanConnectToStreamServer( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>())) .Returns(true); StreamHealthCheckValidationMock.Setup(a => a.ValidateStream( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>(), It.IsAny <int>())) .Returns(false); //This call will trigger health check message sportProcessorRouterActor.Tell(new ProcessSportMsg { Sport = FootabllSportMock.Object.Name }); // //Assert // AwaitAssert(() => { resourceFacadeMock.Verify(a => a.GetSnapshot(), Times.Exactly(2)); PluginMock.Verify(a => a.ProcessSnapshot(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), false), Times.Exactly(2)); PluginMock.Verify(a => a.ProcessSnapshot(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), true), Times.Never); PluginMock.Verify(a => a.ProcessMatchStatus(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id))), Times.Never); SuspensionManagerMock.Verify(a => a.Unsuspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id))), Times.Never); SuspensionManagerMock.Verify(a => a.Suspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), SuspensionReason.SUSPENSION), Times.Once); Assert.AreEqual(StreamListenerState.Streaming, streamListenerActor.State); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); #endregion #region 3rd processing //third time the stream is not valid because of missing sequences //and the stream listener is stopped because of second stream invalid detection in a row due to missing sequences //but Resource is Match Over so a new Stream Listener instance is created and Match Over is processed StreamHealthCheckValidationMock.Reset(); StreamHealthCheckValidationMock.Setup(a => a.CanConnectToStreamServer( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>())) .Returns(true); StreamHealthCheckValidationMock.Setup(a => a.ValidateStream( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>(), It.IsAny <int>())) .Returns(false); //This call will trigger health check message sportProcessorRouterActor.Tell(new ProcessSportMsg { Sport = FootabllSportMock.Object.Name }); streamListenerActorRef = null; try { AwaitAssert(() => { streamListenerActorRef = GetChildActorRef( streamListenerManagerActor, StreamListenerActor.GetName(resourceFacadeMock.Object.Id)); streamListenerActor = GetUnderlyingActor <StreamListenerActor>(streamListenerActorRef); if (streamListenerActor != null) { Assert.AreEqual(StreamListenerState.Stopped, streamListenerActor.State); } }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); } catch (Exception) { //exception could be caught here as Stream Listener Actor becomes stopped //and eventually killed before we actually have the chance to assert for Stopped state } streamListenerActorRef = null; try { AwaitAssert(() => { streamListenerActorRef = GetChildActorRef( streamListenerManagerActor, StreamListenerActor.GetName(resourceFacadeMock.Object.Id)); Assert.IsNull(streamListenerActorRef); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); } catch (Exception) { //exception is expected here as Stream Listener Actor should not exist at this time } resourceFacadeMock.Reset(); StateManagerMock.Reset(); StoreProviderMock.Reset(); SetupCommonMockObjects( /*sport*/ FootabllSportMock.Object.Name, /*fixtureData*/ FixtureSamples.football_matchover_snapshot_2, /*storedData*/ new { Epoch = 2, Sequence = 1, MatchStatus = MatchStatus.InRunning }, out snapshot, out resourceFacadeMock); ServiceMock.Reset(); ServiceMock.Setup(o => o.GetResources(It.Is <string>(s => s.Equals(FootabllSportMock.Object.Name)))) .Returns(new List <IResourceFacade> { resourceFacadeMock.Object }); //This call will trigger stream listener actor creation sportProcessorRouterActor.Tell(new ProcessSportMsg { Sport = FootabllSportMock.Object.Name }); streamListenerActorRef = null; try { AwaitAssert(() => { streamListenerActorRef = GetChildActorRef( streamListenerManagerActor, StreamListenerActor.GetName(resourceFacadeMock.Object.Id)); streamListenerActor = GetUnderlyingActor <StreamListenerActor>(streamListenerActorRef); if (streamListenerActor != null) { Assert.AreEqual(StreamListenerState.Stopped, streamListenerActor.State); } }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); } catch (Exception) { //exception could be caught here as Stream Listener Actor becomes stopped //and eventually killed before we actually have the chance to assert for Stopped state } streamListenerActorRef = null; try { AwaitAssert(() => { streamListenerActorRef = GetChildActorRef( streamListenerManagerActor, StreamListenerActor.GetName(resourceFacadeMock.Object.Id)); Assert.IsNull(streamListenerActorRef); resourceFacadeMock.Verify(a => a.GetSnapshot(), Times.Once); PluginMock.Verify(a => a.ProcessSnapshot(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), false), Times.Never); PluginMock.Verify(a => a.ProcessSnapshot(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), true), Times.Once); PluginMock.Verify(a => a.ProcessMatchStatus(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id))), Times.Never); SuspensionManagerMock.Verify(a => a.Unsuspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id))), Times.Never); SuspensionManagerMock.Verify(a => a.Suspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), SuspensionReason.SUSPENSION), Times.Once); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); } catch (Exception) { //exception is expected here as Stream Listener Actor should not exist at this time } #endregion #region 4th processing //fourth time no Stream Listener is created as Match is already Over and was already processed sportProcessorRouterActor.Tell(new ProcessSportMsg { Sport = FootabllSportMock.Object.Name }); streamListenerActorRef = null; try { AwaitAssert(() => { streamListenerActorRef = GetChildActorRef( streamListenerManagerActor, StreamListenerActor.GetName(resourceFacadeMock.Object.Id)); streamListenerActor = GetUnderlyingActor <StreamListenerActor>(streamListenerActorRef); Assert.NotNull(streamListenerActorRef); Assert.NotNull(streamListenerActor); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); } catch (Exception) { //exception is expected here as Stream Listener Actor should not exist at this time } // //Assert // AwaitAssert(() => { Assert.IsNull(streamListenerActorRef); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); #endregion }
public void ConnectToStreamingServerAndProcessSnapshot() { // //Arrange // Fixture snapshot; Mock <IResourceFacade> resourceFacadeMock; SetupCommonMockObjects( /*sport*/ FootabllSportMock.Object.Name, /*fixtureData*/ FixtureSamples.football_setup_snapshot_2, /*storedData*/ new { Epoch = 3, Sequence = 1, MatchStatus = MatchStatus.Setup }, out snapshot, out resourceFacadeMock); ServiceMock.Setup(o => o.GetResources(It.Is <string>(s => s.Equals(FootabllSportMock.Object.Name)))) .Returns(new List <IResourceFacade> { resourceFacadeMock.Object }); StreamHealthCheckValidationMock.Setup(a => a.CanConnectToStreamServer( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>())) .Returns(false); SettingsMock.SetupGet(a => a.AllowFixtureStreamingInSetupMode).Returns(false); FixtureValidationMock.Setup(a => a.IsSnapshotNeeded( It.IsAny <IResourceFacade>(), It.IsAny <FixtureState>())) .Returns(true); // //Act // var streamListenerManagerActor = ActorOfAsTestActorRef <StreamListenerManagerActor>( Props.Create(() => new StreamListenerManagerActor( SettingsMock.Object, PluginMock.Object, StateManagerMock.Object, SuspensionManagerMock.Object, StreamHealthCheckValidationMock.Object, FixtureValidationMock.Object)), StreamListenerManagerActor.ActorName); var sportProcessorRouterActor = ActorOfAsTestActorRef <SportProcessorRouterActor>( Props.Create(() => new SportProcessorRouterActor(ServiceMock.Object)) .WithRouter(new SmallestMailboxPool(SettingsMock.Object.FixtureCreationConcurrency)), SportProcessorRouterActor.ActorName); sportProcessorRouterActor.Tell(new ProcessSportMsg { Sport = FootabllSportMock.Object.Name }); IActorRef streamListenerActorRef; StreamListenerActor streamListenerActor = null; IActorRef resourceActorRef; IActorRef healthCheckActorRef; //Get child actors instances AwaitAssert(() => { streamListenerActorRef = GetChildActorRef( streamListenerManagerActor, StreamListenerActor.GetName(resourceFacadeMock.Object.Id)); streamListenerActor = GetUnderlyingActor <StreamListenerActor>(streamListenerActorRef); resourceActorRef = GetChildActorRef(streamListenerActorRef, ResourceActor.ActorName); healthCheckActorRef = GetChildActorRef(streamListenerActorRef, StreamHealthCheckActor.ActorName); Assert.NotNull(streamListenerActorRef); Assert.NotNull(streamListenerActor); Assert.NotNull(resourceActorRef); Assert.NotNull(healthCheckActorRef); Assert.AreEqual(StreamListenerState.Initialized, streamListenerActor.State); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); StreamHealthCheckValidationMock.Reset(); StreamHealthCheckValidationMock.Setup(a => a.CanConnectToStreamServer( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>())) .Returns(true); StreamHealthCheckValidationMock.Setup(a => a.ValidateStream( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>(), It.IsAny <int>())) .Returns(true); //This call will trigger health check message sportProcessorRouterActor.Tell(new ProcessSportMsg { Sport = FootabllSportMock.Object.Name }); // //Assert // AwaitAssert(() => { resourceFacadeMock.Verify(a => a.GetSnapshot(), Times.Exactly(2)); PluginMock.Verify(a => a.ProcessSnapshot(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), false), Times.Exactly(2)); PluginMock.Verify(a => a.ProcessSnapshot(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), true), Times.Never); PluginMock.Verify(a => a.ProcessMatchStatus(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id))), Times.Never); SuspensionManagerMock.Verify(a => a.Unsuspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id))), Times.Never); SuspensionManagerMock.Verify(a => a.Suspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), SuspensionReason.SUSPENSION), Times.Never); Assert.AreEqual(StreamListenerState.Streaming, streamListenerActor.State); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); }
public void WhenStartStreamingIsNotRespondingThenStopStreamListener() { // //Arrange // Fixture snapshot; Mock <IResourceFacade> resourceFacadeMock; SetupCommonMockObjects( /*sport*/ FootabllSportMock.Object.Name, /*fixtureData*/ FixtureSamples.football_inplay_snapshot_2, /*storedData*/ new { Epoch = 7, Sequence = 1, MatchStatus = MatchStatus.InRunning }, out snapshot, out resourceFacadeMock); StreamHealthCheckValidationMock.Setup(a => a.CanConnectToStreamServer( It.IsAny <IResourceFacade>(), It.IsAny <StreamListenerState>())) .Returns(true); SettingsMock.SetupGet(o => o.StartStreamingTimeoutInSeconds).Returns(1); SettingsMock.SetupGet(o => o.StartStreamingAttempts).Returns(3); ServiceMock.Setup(o => o.GetResources(It.Is <string>(s => s.Equals(FootabllSportMock.Object.Name)))) .Returns(new List <IResourceFacade> { resourceFacadeMock.Object }); resourceFacadeMock.Reset(); resourceFacadeMock.Setup(o => o.Id).Returns(snapshot.Id); resourceFacadeMock.Setup(o => o.Sport).Returns(FootabllSportMock.Object.Name); resourceFacadeMock.Setup(o => o.MatchStatus).Returns((MatchStatus)Convert.ToInt32(snapshot.MatchStatus)); resourceFacadeMock.Setup(o => o.Content).Returns(new Summary { Id = snapshot.Id, Sequence = snapshot.Sequence, MatchStatus = Convert.ToInt32(snapshot.MatchStatus), StartTime = snapshot.StartTime?.ToString("yyyy-MM-ddTHH:mm:ssZ") }); // //Act // var streamListenerManagerActor = ActorOfAsTestActorRef <StreamListenerManagerActor>( Props.Create(() => new StreamListenerManagerActor( SettingsMock.Object, PluginMock.Object, StateManagerMock.Object, SuspensionManagerMock.Object, StreamHealthCheckValidationMock.Object, FixtureValidationMock.Object)), StreamListenerManagerActor.ActorName); var sportProcessorRouterActor = ActorOfAsTestActorRef <SportProcessorRouterActor>( Props.Create(() => new SportProcessorRouterActor(ServiceMock.Object)) .WithRouter(new SmallestMailboxPool(SettingsMock.Object.FixtureCreationConcurrency)), SportProcessorRouterActor.ActorName); sportProcessorRouterActor.Tell(new ProcessSportMsg { Sport = FootabllSportMock.Object.Name }); //wait for 5 seconds while the health checks run every second and after 3 attempts the manager kills the actor Task.Delay(5000).Wait(); // //Assert // AwaitAssert(() => { resourceFacadeMock.Verify(a => a.GetSnapshot(), Times.Never); PluginMock.Verify(a => a.ProcessSnapshot(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), false), Times.Never); PluginMock.Verify(a => a.ProcessSnapshot(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), true), Times.Never); PluginMock.Verify(a => a.ProcessStreamUpdate(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), false), Times.Never); SuspensionManagerMock.Verify(a => a.Unsuspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id))), Times.Never); SuspensionManagerMock.Verify(a => a.Suspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), SuspensionReason.SUSPENSION), Times.Never); SuspensionManagerMock.Verify(a => a.Suspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), SuspensionReason.FIXTURE_ERRORED), Times.Never); SuspensionManagerMock.Verify(a => a.Suspend(It.Is <Fixture>(f => f.Id.Equals(resourceFacadeMock.Object.Id)), SuspensionReason.DISCONNECT_EVENT), Times.Never); Assert.Throws <AggregateException>(() => { Sys.ActorSelection( streamListenerManagerActor, StreamListenerActor.GetName(resourceFacadeMock.Object.Id)) .ResolveOne(TimeSpan.FromSeconds(5)).Wait(); }).InnerException.Should().BeOfType <ActorNotFoundException>(); }, TimeSpan.FromMilliseconds(ASSERT_WAIT_TIMEOUT), TimeSpan.FromMilliseconds(ASSERT_EXEC_INTERVAL)); }