public async Task Process_CompleteSuccessfully_WhenOutgoingLinkQueueFound() { const string linkName = "abcd"; const string entity = "entity"; ISecurityContext securityContext = Substitute.For <ISecurityContext>(); IEntityLookup entityLookup = Substitute.For <IEntityLookup>(); ILoggerProvider loggerProvider = Substitute.For <ILoggerProvider>(); Entities.IEntity fakeEntity = Substitute.For <Entities.IEntity>(); var deliveryQueue = new DeliveryQueue(); var linkProcessor = new LinkProcessor(securityContext, entityLookup, loggerProvider); entityLookup.Find(Arg.Any <string>()).Returns(fakeEntity); securityContext.IsAuthorized(Arg.Any <Connection>()).Returns(true); fakeEntity.DeliveryQueue.Returns(deliveryQueue); Session session = await TestAmqpHost.OpenAndLinkProcessorAsync(linkProcessor); try { var receiver = new ReceiverLink(session, linkName, entity); deliveryQueue.Enqueue(new Delivery(new Message { Properties = new Properties { MessageId = "msgid6746" } })); Message message = await receiver.ReceiveAsync(); message.Properties.MessageId.ShouldBe("msgid6746"); } finally { await session.Connection.CloseAsync(); } }
public async Task Process_ProcessesRenewLock() { ILogger fakeLogger = Substitute.For <ILogger>(); ILoggerProvider fakeLoggerProvider = Substitute.For <ILoggerProvider>(); fakeLoggerProvider.CreateLogger(Arg.Any <string>()).Returns(fakeLogger); var processor = new ManagementRequestProcessor(fakeLoggerProvider); var lockTokens = new Guid[] { Guid.NewGuid(), Guid.NewGuid() }; var request = new Message(new Map { ["lock-tokens"] = lockTokens }) { ApplicationProperties = new Amqp.Framing.ApplicationProperties { ["operation"] = "com.microsoft:renew-lock" } }; Message response = await TestAmqpHost.ProcessManagementRequestAsync(request, processor); var expirations = (response.Body as Map)?["expirations"] as DateTime[]; response.ApplicationProperties["statusCode"].ShouldBe(200); expirations.Length.ShouldBe(2); fakeLogger.Received(1).Log( LogLevel.Debug, Arg.Any <EventId>(), Arg.Is <FormattedLogValues>(a => a.ToString() == "com.microsoft:renew-lock applied to 2 lock token(s)."), Arg.Any <Exception>(), Arg.Any <Func <FormattedLogValues, Exception, string> >()); }
public async Task Process_CompleteWithError_WhenOutgoingLinkQueueNotFound() { const string linkName = "abcd"; const string entity = "entity"; ISecurityContext securityContext = Substitute.For <ISecurityContext>(); IEntityLookup entityLookup = Substitute.For <IEntityLookup>(); ILoggerProvider loggerProvider = Substitute.For <ILoggerProvider>(); Entities.IEntity fakeEntity = Substitute.For <Entities.IEntity>(); var linkProcessor = new LinkProcessor(securityContext, entityLookup, loggerProvider); fakeEntity.DeliveryQueue.Returns((DeliveryQueue)null); entityLookup.Find(Arg.Any <string>()).Returns(fakeEntity); securityContext.IsAuthorized(Arg.Any <Connection>()).Returns(true); AmqpException exception = null; Session session = await TestAmqpHost.OpenAndLinkProcessorAsync(linkProcessor); try { var receiver = new ReceiverLink(session, linkName, entity); Func <Task> action = async() => await receiver.ReceiveAsync(); linkProcessor.ShouldSatisfyAllConditions( () => exception = action.ShouldThrow <AmqpException>(), () => exception.Error.Condition.ShouldBe((Symbol)ErrorCode.NotFound), () => exception.Error.Description.ShouldBe("Queue not found.") ); } finally { await session.Connection.CloseAsync(); } }
public async Task OnFlow_SendsMessageToReceiverLink() { var message = new Message("x") { Properties = new Properties { CorrelationId = "abc123" } }; IDeliveryQueue fakeDeliveryQueue = Substitute.For <IDeliveryQueue>(); fakeDeliveryQueue .Dequeue(Arg.Any <CancellationToken>()) .Returns(message); var endpoint = new OutgoingLinkEndpoint(fakeDeliveryQueue); ReceiverLink receiver = await TestAmqpHost.OpenAndLinkReceiverAsync(endpoint); try { receiver.SetCredit(1, CreditMode.Manual); Message receivedMessage = await receiver.ReceiveAsync(); receivedMessage.Properties.CorrelationId .ShouldBe(message.Properties.CorrelationId); } finally { await receiver.Session.Connection.CloseAsync(); } }
public async Task Process_ReturnsSuccessStatusCodeInResponse() { var processor = new ManagementRequestProcessor(Substitute.For <ILoggerProvider>()); var request = new Message(); Message response = await TestAmqpHost.ProcessManagementRequestAsync(request, processor); response.ApplicationProperties["statusCode"].ShouldBe(200); }
public async Task Process_CompleteWith200Ok_WhenTokenValid() { const string testMessageId = "rekwest1025847"; var processor = new CbsRequestProcessor(Substitute.For <ISecurityContext>(), Substitute.For <ILoggerProvider>(), Substitute.For <ITokenValidator>()); IDictionary <string, object> responseProperties = await TestAmqpHost.ProcessCbsRequestAsync(testMessageId, processor); responseProperties.ShouldBe(new Dictionary <string, object> { ["CorrelationId"] = testMessageId, ["status-code"] = 200 }); }
public async Task Process_LogSuccess_WhenTokenValid() { ILogger fakeLogger = Substitute.For <ILogger>(); ILoggerProvider fakeLoggerProvider = Substitute.For <ILoggerProvider>(); fakeLoggerProvider.CreateLogger(Arg.Any <string>()).Returns(fakeLogger); var processor = new CbsRequestProcessor(Substitute.For <ISecurityContext>(), fakeLoggerProvider, Substitute.For <ITokenValidator>()); await TestAmqpHost.ProcessCbsRequestAsync("111", processor); fakeLogger.Received(1).Log( LogLevel.Debug, Arg.Any <EventId>(), Arg.Is <FormattedLogValues>(f => f.ToString().StartsWith("Valid $cbs request")), Arg.Any <Exception>(), Arg.Any <Func <FormattedLogValues, Exception, string> >() ); }
public async Task Process_CompleteWith401Unathorized_WhenTokenValid() { const string testMessageId = "someErrorMessageId"; ITokenValidator fakeTokenValidator = Substitute.For <ITokenValidator>(); fakeTokenValidator .When(instance => instance.Validate(Arg.Any <string>())) .Do(_ => throw new ArgumentException("Test")); var processor = new CbsRequestProcessor(Substitute.For <ISecurityContext>(), Substitute.For <ILoggerProvider>(), fakeTokenValidator); IDictionary <string, object> responseProperties = await TestAmqpHost.ProcessCbsRequestAsync(testMessageId, processor); responseProperties.ShouldBe(new Dictionary <string, object> { ["CorrelationId"] = testMessageId, ["status-code"] = 401 }); }
public async Task IsAuthorized_ReturnsFalse_WhenSessionConnectionClosedBeforeAuthorized() { ListenerLink link = null; var authorized = false; ILinkProcessor fakeLinkProcessor = Substitute.For <ILinkProcessor>(); fakeLinkProcessor .When(instance => instance.Process(Arg.Any <AttachContext>())) .Do(c => { AttachContext attachContext = c.ArgAt <AttachContext>(0); link = attachContext.Link; attachContext.Complete(new Error(ErrorCode.IllegalState) { Description = "Test" }); }); ContainerHost host = TestAmqpHost.Open(); try { host.RegisterLinkProcessor(fakeLinkProcessor); Connection connection = await host.ConnectAndAttachAsync(); await connection.CloseAsync(); await Task.Delay(500); var securityContext = new SecurityContext(); securityContext.Authorize(link.Session.Connection); authorized = securityContext.IsAuthorized(link.Session.Connection); } finally { host.Close(); } authorized.ShouldBeFalse(); }
public async Task IsAuthorized_ReturnsTrue_WhenSameConnectionAuthorizedTwice() { var authorized = false; var links = new List <ListenerLink>(); ILinkProcessor fakeLinkProcessor = Substitute.For <ILinkProcessor>(); fakeLinkProcessor .When(instance => instance.Process(Arg.Any <AttachContext>())) .Do(c => { AttachContext attachContext = c.ArgAt <AttachContext>(0); links.Add(attachContext.Link); attachContext.Complete(new Error(ErrorCode.IllegalState) { Description = "Test" }); }); ContainerHost host = TestAmqpHost.Open(); try { host.RegisterLinkProcessor(fakeLinkProcessor); Connection connection = await host.ConnectAndAttachAsync(2); var securityContext = new SecurityContext(); securityContext.Authorize(links[0].Session.Connection); securityContext.Authorize(links[1].Session.Connection); authorized = securityContext.IsAuthorized(links[1].Session.Connection); await connection.CloseAsync(); } finally { host.Close(); } authorized.ShouldBeTrue(); }
public async Task Process_CompleteWithError_WhenIncomingLinkEntityNotFound() { const string linkName = "abcd"; const string entity = "entity"; ISecurityContext securityContext = Substitute.For <ISecurityContext>(); IEntityLookup entityLookup = Substitute.For <IEntityLookup>(); ILoggerProvider loggerProvider = Substitute.For <ILoggerProvider>(); var linkProcessor = new LinkProcessor(securityContext, entityLookup, loggerProvider); entityLookup.Find(Arg.Any <string>()).Returns((Entities.IEntity)null); securityContext.IsAuthorized(Arg.Any <Connection>()).Returns(true); AmqpException exception = null; Session session = await TestAmqpHost.OpenAndLinkProcessorAsync(linkProcessor); try { var sender = new SenderLink(session, linkName, entity); var message = new Message { Properties = new Properties { MessageId = "message1" }, BodySection = new Data { Binary = Encoding.UTF8.GetBytes("hello!") } }; Func <Task> action = async() => await sender.SendAsync(message); linkProcessor.ShouldSatisfyAllConditions( () => exception = action.ShouldThrow <AmqpException>(), () => exception.Error.Condition.ShouldBe((Symbol)ErrorCode.NotFound), () => exception.Error.Description.ShouldBe("Entity not found.") ); } finally { await session.Connection.CloseAsync(); } }
public async Task Process_CompleteSuccessfully_WhenIncomingLinkEntityFound() { const string linkName = "abcd"; const string entity = "myEntity"; ISecurityContext securityContext = Substitute.For <ISecurityContext>(); IEntityLookup entityLookup = Substitute.For <IEntityLookup>(); ILoggerProvider loggerProvider = Substitute.For <ILoggerProvider>(); Entities.IEntity fakeEntity = Substitute.For <Entities.IEntity>(); var linkProcessor = new LinkProcessor(securityContext, entityLookup, loggerProvider); entityLookup.Find(entity).Returns(fakeEntity); securityContext.IsAuthorized(Arg.Any <Connection>()).Returns(true); Session session = await TestAmqpHost.OpenAndLinkProcessorAsync(linkProcessor); try { var sender = new SenderLink(session, linkName, entity); var message = new Message { Properties = new Properties { MessageId = "message173" }, BodySection = new Data { Binary = Encoding.UTF8.GetBytes("hello!") } }; await sender.SendAsync(message); fakeEntity .Received(1) .Post(Arg.Is <Message>(m => m.Properties.MessageId == "message173")); } finally { await session.Connection.CloseAsync(); } }
public async Task Process_CompleteWithError_WhenLinkNameEmpty() { const string emptyLinkName = ""; const string entity = "entity"; ISecurityContext securityContext = Substitute.For <ISecurityContext>(); IEntityLookup entityLookup = Substitute.For <IEntityLookup>(); ILoggerProvider loggerProvider = Substitute.For <ILoggerProvider>(); var linkProcessor = new LinkProcessor(securityContext, entityLookup, loggerProvider); AmqpException exception = null; Session session = await TestAmqpHost.OpenAndLinkProcessorAsync(linkProcessor); try { var sender = new SenderLink(session, emptyLinkName, entity); var message = new Message { Properties = new Properties { MessageId = "message1" }, BodySection = new Data { Binary = Encoding.UTF8.GetBytes("hello!") } }; Func <Task> action = async() => await sender.SendAsync(message); linkProcessor.ShouldSatisfyAllConditions( () => exception = action.ShouldThrow <AmqpException>(), () => exception.Error.Condition.ShouldBe((Symbol)ErrorCode.InvalidField), () => exception.Error.Description.ShouldBe("Empty link name not allowed.") ); } finally { await session.Connection.CloseAsync(); } }
public async Task Process_LogError_WhenTokenInvalid() { var testException = new ArgumentException("Test"); ILogger fakeLogger = Substitute.For <ILogger>(); ILoggerProvider fakeLoggerProvider = Substitute.For <ILoggerProvider>(); fakeLoggerProvider.CreateLogger(Arg.Any <string>()).Returns(fakeLogger); ITokenValidator fakeTokenValidator = Substitute.For <ITokenValidator>(); fakeTokenValidator .When(instance => instance.Validate(Arg.Any <string>())) .Do(_ => throw testException); var processor = new CbsRequestProcessor(Substitute.For <ISecurityContext>(), fakeLoggerProvider, fakeTokenValidator); await TestAmqpHost.ProcessCbsRequestAsync("abc", processor); fakeLogger.Received(1).Log( LogLevel.Error, Arg.Any <EventId>(), Arg.Is <FormattedLogValues>(f => f.ToString().StartsWith("Failed to validate $cbs request")), testException, Arg.Any <Func <FormattedLogValues, Exception, string> >() ); }
public async Task Process_LogsUnsupportedOperation(string operation) { ILogger fakeLogger = Substitute.For <ILogger>(); ILoggerProvider fakeLoggerProvider = Substitute.For <ILoggerProvider>(); fakeLoggerProvider.CreateLogger(Arg.Any <string>()).Returns(fakeLogger); var processor = new ManagementRequestProcessor(fakeLoggerProvider); var request = new Message { ApplicationProperties = new Amqp.Framing.ApplicationProperties { ["operation"] = operation } }; await TestAmqpHost.ProcessManagementRequestAsync(request, processor); fakeLogger.Received(1).Log( LogLevel.Debug, Arg.Any <EventId>(), Arg.Is <FormattedLogValues>(a => a.ToString() == $"Unsupported operation {operation}."), Arg.Any <Exception>(), Arg.Any <Func <FormattedLogValues, Exception, string> >()); }