using System; using System.Collections.Generic; using System.Threading; using Moq; using NUnit.Framework; using NzbDrone.Common.Messaging; using NzbDrone.Test.Common; using FluentAssertions; namespace NzbDrone.Common.Test.EventingTests { [TestFixture] public class MessageAggregatorEventTests : TestBase { private Mock> HandlerA1; private Mock> HandlerA2; private Mock> HandlerB1; private Mock> HandlerB2; private Mock> AsyncHandlerA1; [SetUp] public void Setup() { HandlerA1 = new Mock>(); HandlerA2 = new Mock>(); HandlerB1 = new Mock>(); HandlerB2 = new Mock>(); AsyncHandlerA1 = new Mock>(); Mocker.GetMock() .Setup(c => c.BuildAll>()) .Returns(new List> { HandlerA1.Object, HandlerA2.Object }); Mocker.GetMock() .Setup(c => c.BuildAll>()) .Returns(new List> { HandlerB1.Object, HandlerB2.Object }); } [Test] public void should_publish_event_to_handlers() { var eventA = new EventA(); Subject.PublishEvent(eventA); HandlerA1.Verify(c => c.Handle(eventA), Times.Once()); HandlerA2.Verify(c => c.Handle(eventA), Times.Once()); } [Test] public void should_not_publish_to_incompatible_handlers() { var eventA = new EventA(); Subject.PublishEvent(eventA); HandlerA1.Verify(c => c.Handle(eventA), Times.Once()); HandlerA2.Verify(c => c.Handle(eventA), Times.Once()); HandlerB1.Verify(c => c.Handle(It.IsAny()), Times.Never()); HandlerB2.Verify(c => c.Handle(It.IsAny()), Times.Never()); } [Test] public void broken_handler_should_not_effect_others_handler() { var eventA = new EventA(); HandlerA1.Setup(c => c.Handle(It.IsAny())) .Throws(new NotImplementedException()); Subject.PublishEvent(eventA); HandlerA1.Verify(c => c.Handle(eventA), Times.Once()); HandlerA2.Verify(c => c.Handle(eventA), Times.Once()); ExceptionVerification.ExpectedErrors(1); } [Test] public void should_queue_multiple_async_events() { var eventA = new EventA(); var handlers = new List> { AsyncHandlerA1.Object, AsyncHandlerA1.Object, AsyncHandlerA1.Object, AsyncHandlerA1.Object, AsyncHandlerA1.Object, AsyncHandlerA1.Object, AsyncHandlerA1.Object, }; Mocker.GetMock() .Setup(c => c.BuildAll>()) .Returns(new List>()); Mocker.GetMock() .Setup(c => c.BuildAll>()) .Returns(handlers); var counter = new ConcurrencyCounter(handlers.Count); AsyncHandlerA1.Setup(c => c.HandleAsync(It.IsAny())) .Callback(c => { var id = counter.Start(); Thread.Sleep(1000); counter.Stop(id); }); Subject.PublishEvent(eventA); counter.WaitForAllItems(); counter.MaxThreads.Should().Be(2); } } public class EventA : IEvent { } public class EventB : IEvent { } }