public async Task When_Reader_Completes_When_All_Readers_Completed() { // Arrange using var multiplexer = new MergingMultiplexer(10, _outputHelper.ToLogger <MergingMultiplexer>()); var cts = new CancellationTokenSource(); var channel1 = Channel.CreateBounded <IQueueMessageContext>(10); var channel2 = Channel.CreateBounded <IQueueMessageContext>(10); multiplexer.ReadFrom(channel1); multiplexer.ReadFrom(channel2); // Act await multiplexer.RunAsync(cts.Token); var multiplexerRunTask = ReadAllMessages(multiplexer); channel1.Writer.Complete(); channel2.Writer.Complete(); // Assert await Patiently.AssertThatAsync(_outputHelper, () => multiplexerRunTask.IsCompletedSuccessfully); cts.Cancel(); }
// Quick fix for user entity manipulation outside of this db context // TODO: Fix properly static public async Task <User> GetUserEntityAsync(this BotDatabaseContext context, IUser user) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } // Update cached displayname var displayName = user.Username; var result = await Patiently.HandleDbConcurrency(async() => { var userEntity = await context.Users.AsQueryable().FirstOrDefaultAsync(o => o.Id == user.Id); if (userEntity != null && userEntity.Name != displayName) { userEntity.Name = displayName; await context.SaveChangesAsync(); } return(userEntity); }); return(result); }
public async Task ThenExceptionIsRecordedInMonitoring() { _handler.WaitUntilCompletion(15.Seconds()).ShouldBe(true); await Patiently.VerifyExpectationAsync( () => Monitoring.Received().HandleException(Arg.Any <string>())); }
public async Task FailedMessageIsNotRemovedFromQueue() { // The un-handled one is however. await Patiently.VerifyExpectationAsync( () => Sqs.DidNotReceiveWithAnyArgs().DeleteMessage( Arg.Any <DeleteMessageRequest>())); }
public async Task Then_Both_Handlers_Receive_Messages() { // Arrange var genericHandler = new InspectableHandler <GenericMessage <SimpleMessage> >(); var nonGenericHandler = new InspectableHandler <SimpleMessage>(); var services = GivenJustSaying() .ConfigureJustSaying((builder) => builder.WithLoopbackTopic <GenericMessage <SimpleMessage> >($"{UniqueName}-generic")) .ConfigureJustSaying((builder) => builder.WithLoopbackTopic <SimpleMessage>($"{UniqueName}-nongeneric")) .AddSingleton <IHandlerAsync <GenericMessage <SimpleMessage> > >(genericHandler) .AddSingleton <IHandlerAsync <SimpleMessage> >(nonGenericHandler); await WhenAsync( services, async (publisher, listener, serviceProvider, cancellationToken) => { await listener.StartAsync(cancellationToken); await publisher.StartAsync(cancellationToken); // Act await publisher.PublishAsync(new GenericMessage <SimpleMessage>(), cancellationToken); await publisher.PublishAsync(new SimpleMessage(), cancellationToken); await Patiently.AssertThatAsync(OutputHelper, () => { genericHandler.ReceivedMessages.ShouldHaveSingleItem(); nonGenericHandler.ReceivedMessages.ShouldHaveSingleItem(); }); }); }
public async Task EventPublicationWasAttemptedTheConfiguredNumberOfTimes() { await Patiently.VerifyExpectationAsync(() => _publisher .Received(PublishAttempts) .Publish(Arg.Any <GenericMessage>())); }
public async Task Then_The_Message_Is_Handled() { // Arrange var handler = new ThrowingHandler(); var monitoring = Substitute.For <IMessageMonitor>(); var services = GivenJustSaying() .ConfigureJustSaying((builder) => builder.WithLoopbackQueue <SimpleMessage>(UniqueName)) .ConfigureJustSaying((builder) => builder.Services((options) => options.WithMessageMonitoring(() => monitoring))) .AddSingleton <IHandlerAsync <SimpleMessage> >(handler); var message = new SimpleMessage(); await WhenAsync( services, async (publisher, listener, cancellationToken) => { await listener.StartAsync(cancellationToken); await publisher.StartAsync(cancellationToken); // Act await publisher.PublishAsync(message, cancellationToken); await Patiently.AssertThatAsync(OutputHelper, () => { handler.MessageReceived.ShouldNotBeNull(); monitoring.Received().HandleException(Arg.Any <Type>()); }); }); }
public async Task CorrectQueueIsPolled() { await Patiently.VerifyExpectationAsync(() => Sqs.Received().ReceiveMessageAsync( Arg.Is <ReceiveMessageRequest>(x => x.QueueUrl == QueueUrl), Arg.Any <CancellationToken>())); }
public async Task TheMaxMessageAllowanceIsGrabbed() { await Patiently.VerifyExpectationAsync(() => Sqs.Received().ReceiveMessageAsync( Arg.Is <ReceiveMessageRequest>(x => x.MaxNumberOfMessages == 10), Arg.Any <CancellationToken>())); }
public async Task Then_The_Error_Queue_Is_Not_Created() { // Arrange ILoggerFactory loggerFactory = OutputHelper.ToLoggerFactory(); IAwsClientFactory clientFactory = CreateClientFactory(); var client = clientFactory.GetSqsClient(Region); var queue = new SqsQueueByName( Region, UniqueName, client, 1, loggerFactory); // Act await queue.CreateAsync(new SqsBasicConfiguration() { ErrorQueueOptOut = true }); // Assert await Patiently.AssertThatAsync( OutputHelper, async() => !await queue.ErrorQueue.ExistsAsync(CancellationToken.None)); }
public async Task QueueIsCreated() { async Task QueueIsCreatedInner() { var queue = new SqsQueueByName( TestFixture.Region, QueueName, Client, 0, TestFixture.LoggerFactory); await Patiently.AssertThatAsync( () => queue.ExistsAsync(), TimeSpan.FromSeconds(65)); } var task = QueueIsCreatedInner(); if (task == await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(70)))) { await task; } else { throw new TimeoutException(); } }
public async Task MessageIsLocked() { await Patiently.VerifyExpectationAsync( () => MessageLock.Received().TryAquireLock( Arg.Is <string>(a => a.Contains(DeserialisedMessage.Id.ToString())), TimeSpan.FromSeconds(_expectedtimeout))); }
public async Task Sqs_Policy_Is_Applied_With_Wildcard() { // Arrange var handler = new ExactlyOnceHandlerWithTimeout(); var services = GivenJustSaying() .ConfigureJustSaying((builder) => builder.WithLoopbackTopic <TopicA>(UniqueName)) .ConfigureJustSaying((builder) => builder.WithLoopbackTopic <TopicB>(UniqueName)) .AddJustSayingHandler <TopicA, HandlerA>() .AddJustSayingHandler <TopicB, HandlerB>(); await WhenAsync( services, async (publisher, listener, serviceProvider, cancellationToken) => { listener.Start(cancellationToken); var clientFactory = serviceProvider.GetRequiredService <MessagingBusBuilder>().BuildClientFactory(); var loggerFactory = serviceProvider.GetRequiredService <ILoggerFactory>(); var client = clientFactory.GetSqsClient(Region); var queue = new SqsQueueByName(Region, UniqueName, client, 0, loggerFactory); await Patiently.AssertThatAsync(() => queue.ExistsAsync(), 60.Seconds()); dynamic policyJson = JObject.Parse(queue.Policy); policyJson.Statement.Count.ShouldBe(1, $"Expecting 1 statement in Sqs policy but found {policyJson.Statement.Count}."); }); }
[Then, Timeout(70000)] // ToDo: Sorry about this, but SQS is a little slow to verify against. Can be better I'm sure? ;) public async Task QueueIsCreated() { var queue = new SqsQueueByName(RegionEndpoint.EUWest1, QueueName, CreateMeABus.DefaultClientFactory().GetSqsClient(RegionEndpoint.EUWest1), 0); await Patiently.AssertThatAsync( queue.Exists, TimeSpan.FromSeconds(65)); }
[Then, Timeout(70000)] // ToDo: Sorry about this, but SQS is a little slow to verify against. Can be better I'm sure? ;) public async Task QueueIsCreated() { var queue = new SqsQueueByName(RegionEndpoint.EUWest1, QueueName, Client, 0, Substitute.For <ILoggerFactory>()); await Patiently.AssertThatAsync( queue.Exists, TimeSpan.FromSeconds(65)); }
private async Task ThenTheSubscriberReceivesBothMessages() { await Patiently.AssertThatAsync( () => _handler.HasReceived(_message1)); await Patiently.AssertThatAsync( () => _handler.HasReceived(_message2)); }
public async Task SqsPolicyWithAWildcardIsApplied() { var queue = new SqsQueueByName(RegionEndpoint.EUWest1, QueueName, Client, 0); await Patiently.AssertThatAsync(queue.Exists, TimeSpan.FromSeconds(60)); dynamic policyJson = JObject.Parse(queue.Policy); Assert.IsTrue(policyJson.Statement.Count == 1, $"Expecting 1 statement in Sqs policy but found {policyJson.Statement.Count}"); }
public async Task SubscribersStartedUp() { await Patiently.AssertThatAsync(OutputHelper, () => { _queue1.ReceiveMessageRequests.Count.ShouldBeGreaterThan(0); _queue2.ReceiveMessageRequests.Count.ShouldBeGreaterThan(0); }); }
public async Task Buffer_Is_Filled() { using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)); var _ = _messageReceiveBuffer.RunAsync(cts.Token); await Patiently.AssertThatAsync(_outputHelper, () => _callCount > 0); _callCount.ShouldBeGreaterThan(0); }
public async Task SqsPolicyWithAWildcardIsApplied() { var queue = new SqsQueueByName(RegionEndpoint.EUWest1, QueueName, Client, 0, Substitute.For <ILoggerFactory>()); await Patiently.AssertThatAsync(queue.Exists, TimeSpan.FromSeconds(60)); dynamic policyJson = JObject.Parse(queue.Policy); policyJson.Statement.Count.ShouldBe(1, $"Expecting 1 statement in Sqs policy but found {policyJson.Statement.Count}"); }
public async Task Subscriber_Not_Started_No_Buffer_Filled_Then_No_More_Messages_Requested() { // Arrange int messagesFromQueue = 0; int messagesDispatched = 0; int receivebufferSize = 2; int multiplexerCapacity = 2; // plus one "in flight" between buffer and multiplexer int expectedReceiveFromQueueCount = receivebufferSize + multiplexerCapacity + 1; var sqsQueue = TestQueue(() => Interlocked.Increment(ref messagesFromQueue)); IMessageReceiveBuffer buffer = CreateMessageReceiveBuffer(sqsQueue, receivebufferSize); IMessageDispatcher dispatcher = new FakeDispatcher(() => Interlocked.Increment(ref messagesDispatched)); IMultiplexerSubscriber consumer1 = CreateSubscriber(dispatcher); IMultiplexer multiplexer = CreateMultiplexer(multiplexerCapacity); multiplexer.ReadFrom(buffer.Reader); consumer1.Subscribe(multiplexer.GetMessagesAsync()); // need to start the multiplexer before calling Messages using var cts = new CancellationTokenSource(); // Act and Assert var multiplexerCompletion = multiplexer.RunAsync(cts.Token); var bufferCompletion = buffer.RunAsync(cts.Token); cts.CancelAfter(TimeSpan.FromSeconds(3)); await multiplexerCompletion.HandleCancellation(); await Assert.ThrowsAnyAsync <OperationCanceledException>(() => bufferCompletion); await Patiently.AssertThatAsync(OutputHelper, () => { messagesFromQueue.ShouldBe(expectedReceiveFromQueueCount); messagesDispatched.ShouldBe(0); return(true); }); // Starting the consumer after the token is cancelled will not dispatch messages await Assert.ThrowsAnyAsync <OperationCanceledException>(() => consumer1.RunAsync(cts.Token)); await Patiently.AssertThatAsync(OutputHelper, () => { messagesFromQueue.ShouldBe(expectedReceiveFromQueueCount); messagesDispatched.ShouldBe(0); return(true); }); }
public async Task HandleMessageFromQueueLogs_ShouldHaveContext(bool handlerShouldSucceed, LogLevel level, string status, string exceptionMessage) { var handler = new InspectableHandler <SimpleMessage>() { ShouldSucceed = handlerShouldSucceed, }; if (exceptionMessage != null) { handler.OnHandle = msg => throw new Exception(exceptionMessage); } var services = GivenJustSaying(levelOverride: LogLevel.Information) .ConfigureJustSaying( (builder) => builder.WithLoopbackQueue <SimpleMessage>(UniqueName) .Subscriptions(sub => sub.WithDefaults(sgb => sgb.WithDefaultConcurrencyLimit(10)))) .AddSingleton <IHandlerAsync <SimpleMessage> >(handler); var sp = services.BuildServiceProvider(); var cts = new CancellationTokenSource(); var publisher = sp.GetRequiredService <IMessagePublisher>(); await publisher.StartAsync(cts.Token); await sp.GetRequiredService <IMessagingBus>().StartAsync(cts.Token); var message = new SimpleMessage(); await publisher.PublishAsync(message, cts.Token); await Patiently.AssertThatAsync(() => handler.ReceivedMessages .ShouldHaveSingleItem() .Id.ShouldBe(message.Id)); var testLogger = sp.GetRequiredService <ITestLoggerSink>(); await Patiently.AssertThatAsync(() => { var handleMessage = testLogger.LogEntries .SingleOrDefault(le => le.OriginalFormat == "{Status} handling message with Id '{MessageId}' of type {MessageType} in {TimeToHandle}ms."); handleMessage.ShouldNotBeNull(); handleMessage.LogLevel.ShouldBe(level); handleMessage.Exception?.Message.ShouldBe(exceptionMessage); var propertyMap = new Dictionary <string, object>(handleMessage.Properties); propertyMap.ShouldContainKeyAndValue("Status", status); propertyMap.ShouldContainKeyAndValue("MessageId", message.Id); propertyMap.ShouldContainKeyAndValue("MessageType", message.GetType().FullName); propertyMap.ShouldContainKey("TimeToHandle"); }); cts.Cancel(); }
public async Task AllMessagesAreClearedFromQueue() { await Patiently.VerifyExpectationAsync( () => SerialisationRegister.Received(2).DeserializeMessage( Arg.Any<string>())); await Patiently.VerifyExpectationAsync( () =>Sqs.Received().DeleteMessage( Arg.Any<DeleteMessageRequest>())); }
public async Task SqsPolicyWithAWildcardIsApplied() { var queue = new SqsQueueByName(Region, QueueName, Client, 0, TestFixture.LoggerFactory); await Patiently.AssertThatAsync(() => queue.ExistsAsync(), TimeSpan.FromSeconds(60)); dynamic policyJson = JObject.Parse(queue.Policy); policyJson.Statement.Count.ShouldBe(1, $"Expecting 1 statement in Sqs policy but found {policyJson.Statement.Count}"); }
public async Task Sqs_Client_Throwing_Exceptions_Continues_To_Request_Messages() { // Arrange int messagesRequested = 0; int messagesDispatched = 0; IEnumerable <Message> GetMessages() { Interlocked.Increment(ref messagesRequested); throw new Exception(); } var queue = new FakeSqsQueue(ct => Task.FromResult(GetMessages())); var queues = new List <ISqsQueue> { queue }; IMessageDispatcher dispatcher = new FakeDispatcher(() => { Interlocked.Increment(ref messagesDispatched); }); var defaults = new SubscriptionGroupSettingsBuilder() .WithDefaultConcurrencyLimit(8); var settings = new Dictionary <string, SubscriptionGroupConfigBuilder> { { "test", new SubscriptionGroupConfigBuilder("test").AddQueues(queues) }, }; var subscriptionGroupFactory = new SubscriptionGroupFactory( dispatcher, MessageMonitor, LoggerFactory); ISubscriptionGroup collection = subscriptionGroupFactory.Create(defaults, settings); var cts = new CancellationTokenSource(); // Act var runTask = collection.RunAsync(cts.Token); await Patiently.AssertThatAsync(_outputHelper, () => { messagesRequested.ShouldBeGreaterThan(1, $"but was {messagesRequested}"); messagesDispatched.ShouldBe(0, $"but was {messagesDispatched}"); }); cts.Cancel(); await runTask.HandleCancellation(); }
public async Task CanSubscribeUsingQueueArn() { IAwsClientFactory clientFactory = CreateClientFactory(); var sqsClient = clientFactory.GetSqsClient(Region); var snsClient = clientFactory.GetSnsClient(Region); var queueResponse = await sqsClient.CreateQueueAsync(UniqueName); var anotherUniqueName = $"{Guid.NewGuid():N}-integration-tests"; var topicResponse = await snsClient.CreateTopicAsync(anotherUniqueName); var subscriptionArn = await snsClient.SubscribeQueueAsync(topicResponse.TopicArn, sqsClient, queueResponse.QueueUrl); var queueArn = (await sqsClient.GetQueueAttributesAsync(queueResponse.QueueUrl, new List <string> { SQSConstants.ATTRIBUTE_QUEUE_ARN })).Attributes[SQSConstants.ATTRIBUTE_QUEUE_ARN]; var handler = new InspectableHandler <SimpleMessage>(); var services = GivenJustSaying() .ConfigureJustSaying(builder => builder .Subscriptions(c => c.ForQueueArn <SimpleMessage>(queueArn)) .Publications(c => c.WithTopicArn <SimpleMessage>(topicResponse.TopicArn) ) ) .AddJustSayingHandlers(new[] { handler }); string content = Guid.NewGuid().ToString(); var message = new SimpleMessage { Content = content }; await WhenAsync( services, async (publisher, listener, serviceProvider, cancellationToken) => { await listener.StartAsync(cancellationToken); await publisher.StartAsync(cancellationToken); await publisher.PublishAsync(message, cancellationToken); // Assert await Patiently.AssertThatAsync(OutputHelper, () => { handler.ReceivedMessages.ShouldHaveSingleItem().Content.ShouldBe(content); }); }); }
public async Task ThenItIsUsed() { // Arrange var handler = new InspectableHandler <SimpleMessage>(); var accessor = new RecordingMessageContextAccessor(new MessageContextAccessor()); var subject = Guid.NewGuid().ToString(); var subjectProvider = new ConstantSubjectProvider(subject); var services = GivenJustSaying() .ConfigureJustSaying((builder) => builder.WithLoopbackTopic <SimpleMessage>(UniqueName)) .ConfigureJustSaying(builder => builder.Services(s => s.WithMessageContextAccessor(() => accessor))) .ConfigureJustSaying((builder) => builder.Messaging(m => m.WithMessageSubjectProvider(subjectProvider))) .AddSingleton <IHandlerAsync <SimpleMessage> >(handler); var id = Guid.NewGuid(); var message = new SimpleMessage() { Id = id }; using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)); await WhenAsync( services, async (publisher, listener, cancellationToken) => { await listener.StartAsync(cancellationToken); await publisher.StartAsync(cancellationToken); // Let's send an OrderPlaced, but the subject will be a GUID // because of the custom subject provider await publisher.PublishAsync(message, cancellationToken); await Patiently.AssertThatAsync(OutputHelper, () => { var receivedMessage = handler.ReceivedMessages.ShouldHaveSingleItem(); receivedMessage.Id.ShouldBe(id); var context = accessor.ValuesWritten.ShouldHaveSingleItem(); dynamic json = JsonConvert.DeserializeObject(context.Message.Body); string subject = json.Subject; subject.ShouldBe(subject); }); }); }
protected override async Task WhenAsync() { MiddlewareMap.Add <SimpleMessage>(_queue.QueueName, Middleware); var cts = new CancellationTokenSource(); var completion = SystemUnderTest.RunAsync(cts.Token); await Patiently.AssertThatAsync(OutputHelper, () => Handler.ReceivedMessages.Any()); cts.Cancel(); await Assert.ThrowsAnyAsync <OperationCanceledException>(() => completion); }
public async Task Add_Different_Handler_Per_Queue() { // Arrange string group1 = "group1"; string group2 = "group2"; string queueName1 = "queue1"; string queueName2 = "queue2"; JustSaying.JustSayingBus bus = CreateBus(); var handler1 = new InspectableHandler <TestJustSayingMessage>(); var handler2 = new InspectableHandler <TestJustSayingMessage>(); bus.AddMessageHandler(queueName1, () => handler1); bus.AddMessageHandler(queueName2, () => handler2); ISqsQueue queue1 = TestQueue(bus.SerializationRegister, queueName1); ISqsQueue queue2 = TestQueue(bus.SerializationRegister, queueName2); bus.AddQueue(group1, queue1); bus.AddQueue(group2, queue2); using var cts = new CancellationTokenSource(); // Act await bus.StartAsync(cts.Token); await Patiently.AssertThatAsync(_outputHelper, () => { handler1.ReceivedMessages.Count.ShouldBeGreaterThan(0); handler2.ReceivedMessages.Count.ShouldBeGreaterThan(0); }); cts.Cancel(); await bus.Completion; foreach (var message in handler1.ReceivedMessages) { message.QueueName.ShouldBe(queueName1); } foreach (var message in handler2.ReceivedMessages) { message.QueueName.ShouldBe(queueName2); } bus.Dispose(); }
public async Task Then_The_Message_Is_Handled() { // Arrange var handler = new InspectableHandler <SimpleMessage>(); var services = GivenJustSaying() .ConfigureJustSaying((builder) => builder .Publications((options) => options.WithTopic <SimpleMessage>(configure => { configure.WithName("my-special-topic"); })) .Subscriptions((options) => options.ForTopic <SimpleMessage>("my-special-topic", subscriptionBuilder => { subscriptionBuilder.WithName(UniqueName); }))) .AddSingleton <IHandlerAsync <SimpleMessage> >(handler); string content = Guid.NewGuid().ToString(); var message = new SimpleMessage() { Content = content }; string json = ""; await WhenAsync( services, async (publisher, listener, cancellationToken) => { await listener.StartAsync(cancellationToken); await publisher.StartAsync(cancellationToken); var listenerJson = JsonConvert.SerializeObject(listener.Interrogate(), Formatting.Indented); var publisherJson = JsonConvert.SerializeObject(publisher.Interrogate(), Formatting.Indented); await publisher.PublishAsync(message, cancellationToken); json = string.Join($"{Environment.NewLine}{Environment.NewLine}", listenerJson, publisherJson) .Replace(UniqueName, "integrationTestQueueName", StringComparison.Ordinal); await Patiently.AssertThatAsync(OutputHelper, () => handler.ReceivedMessages.Any(x => x.Content == content).ShouldBeTrue()); }); json.ShouldMatchApproved(opt => opt.SubFolder("Approvals")); }