public void SetsExecutionTimeOnCommandWhenInvokedWithoutBreakerAndCommandSucceeds()
            {
                // Arrange

                var key      = AnyString;
                var groupKey = GroupKey.Named(key);

                var mockMetricEvents   = new Mock <IMetricEvents>();
                var mockBreakerInvoker = new Mock <IBreakerInvoker>();

                var mockBulkhead = new Mock <ISemaphoreBulkhead>();

                mockBulkhead.Setup(m => m.TryEnter()).Returns(true);
                mockBulkhead.SetupGet(m => m.Name).Returns(key);

                var mockBulkheadFactory = new Mock <IBulkheadFactory>(MockBehavior.Strict);

                mockBulkheadFactory.Setup(m => m.GetBulkhead(groupKey)).Returns(mockBulkhead.Object);

                var mockConfig = new MjolnirConfiguration {
                    UseCircuitBreakers = false
                };
                // Pass false for useCircuitBreakers to bypass the breaker; we're testing that here.
                var invoker = new BulkheadInvoker(mockBreakerInvoker.Object, mockBulkheadFactory.Object, mockMetricEvents.Object, mockConfig);
                var command = new ConfigurableKeyCommand(key);

                // Act

                invoker.ExecuteWithBulkhead(command, CancellationToken.None);

                // Assert

                Assert.True(command.ExecutionTimeMillis > 0);
            }
            public void FiresMetricEventWhenRejected()
            {
                // Arrange

                var key      = AnyString;
                var groupKey = GroupKey.Named(key);

                var mockMetricEvents   = new Mock <IMetricEvents>();
                var mockBreakerInvoker = new Mock <IBreakerInvoker>();

                var mockBulkhead = new Mock <ISemaphoreBulkhead>();

                mockBulkhead.Setup(m => m.TryEnter()).Returns(false);
                mockBulkhead.SetupGet(m => m.Name).Returns(key);

                var mockBulkheadFactory = new Mock <IBulkheadFactory>(MockBehavior.Strict);

                mockBulkheadFactory.Setup(m => m.GetBulkhead(groupKey)).Returns(mockBulkhead.Object);

                var mockConfig = new MjolnirConfiguration {
                    UseCircuitBreakers = true
                };
                // The breaker invoker behavior doesn't matter here, we shouldn't get to the point
                // where we try to use it.
                var invoker = new BulkheadInvoker(mockBreakerInvoker.Object, mockBulkheadFactory.Object, mockMetricEvents.Object, mockConfig);
                var command = new ConfigurableKeyCommand(key);

                // Act + Assert

                Assert.Throws <BulkheadRejectedException>(() => invoker.ExecuteWithBulkhead(command, CancellationToken.None));

                mockMetricEvents.Verify(m => m.RejectedByBulkhead(key, command.Name));
            }
            public void FiresMetricEventWhenEnteringAndLeavingBulkheadAndCommandSucceeds()
            {
                // Arrange

                var key      = AnyString;
                var groupKey = GroupKey.Named(key);

                var mockMetricEvents   = new Mock <IMetricEvents>();
                var mockBreakerInvoker = new Mock <IBreakerInvoker>();

                var mockBulkhead = new Mock <ISemaphoreBulkhead>();

                mockBulkhead.Setup(m => m.TryEnter()).Returns(true);
                mockBulkhead.SetupGet(m => m.Name).Returns(key);

                var mockBulkheadFactory = new Mock <IBulkheadFactory>(MockBehavior.Strict);

                mockBulkheadFactory.Setup(m => m.GetBulkhead(groupKey)).Returns(mockBulkhead.Object);

                var mockConfig = new MjolnirConfiguration {
                    UseCircuitBreakers = false
                };

                // The breaker invoker behavior doesn't matter here, we shouldn't get to the point
                // where we try to use it. Pass a "false" value for useCircuitBreakers to help
                // ensure that.
                var invoker = new BulkheadInvoker(mockBreakerInvoker.Object, mockBulkheadFactory.Object, mockMetricEvents.Object, mockConfig);
                var command = new ConfigurableKeyCommand(key);

                // Act

                invoker.ExecuteWithBulkhead(command, CancellationToken.None);

                // Assert

                mockMetricEvents.Verify(m => m.EnterBulkhead(key, command.Name));
                mockMetricEvents.Verify(m => m.LeaveBulkhead(key, command.Name));
            }