Beispiel #1
0
        public void Receive_with_non_empty_queue_waits_time_specified_for_max_num_messages()
        {
            var qUrl = helper.CreateQueue();

            helper.SendMessages(qUrl, count: 3);

            var sw = Stopwatch.StartNew();

            var response = client.ReceiveMessage(new ReceiveMessageRequest
            {
                QueueUrl            = qUrl,
                MaxNumberOfMessages = 4,
                VisibilityTimeout   = 30,
                WaitTimeSeconds     = 2
            });

            sw.Stop();

            SqsTestAssert.FakeEqualRealGreater(3, 1, response.Messages.Count);

            if (SqsTestAssert.IsFakeClient)
            {   // SQS support for long polling doesn't guarantee a specific wait time oddly
                Assert.GreaterOrEqual(sw.ElapsedMilliseconds, 2000);
            }
        }
Beispiel #2
0
        public void Messages_with_null_Response_is_published_to_OutMQ()
        {
            var msgsReceived = 0;

            using (var mqServer = CreateMqServer())
            {
                mqServer.RegisterHandler <HelloOut>(m =>
                {
                    Interlocked.Increment(ref msgsReceived);
                    return(null);
                });

                mqServer.Start();

                using (var mqClient = mqServer.MessageFactory.CreateMessageQueueClient())
                {
                    mqClient.Publish(new HelloOut
                    {
                        Name = "Into the Void"
                    });

                    var msg = mqClient.Get <HelloOut>(QueueNames <HelloOut> .Out, TimeSpan.FromSeconds(30));

                    Assert.IsNotNull(msg, "Should have received msg from OUT queue but did not");

                    var response = msg.GetBody();

                    SqsTestAssert.WaitUntilTrueOrTimeout(() => msgsReceived >= 1, timeoutSeconds: 1);

                    Assert.That(response.Name, Is.EqualTo("Into the Void"));
                    Assert.That(msgsReceived, Is.EqualTo(1));
                }
            }
        }
Beispiel #3
0
        public void Can_receive_and_process_standard_request_reply_combo()
        {
            var mqHost = CreateMqServer();

            string messageReceived = null;

            mqHost.RegisterHandler <Hello>(m => new HelloResponse
            {
                Result = "Hello, " + m.GetBody().Name
            });

            mqHost.RegisterHandler <HelloResponse>(m =>
            {
                messageReceived = m.GetBody().Result;
                return(null);
            });

            mqHost.Start();

            var mqClient = mqHost.MessageFactory.CreateMessageQueueClient();

            var dto = new Hello
            {
                Name = "ServiceStack"
            };

            mqClient.Publish(dto);

            SqsTestAssert.WaitUntilTrueOrTimeout(() => messageReceived != null &&
                                                 messageReceived.Equals("Hello, ServiceStack"),
                                                 timeoutSeconds: 12);

            Assert.That(messageReceived, Is.EqualTo("Hello, ServiceStack"));
        }
Beispiel #4
0
        private void RunHandlerOnMultipleThreads(int noOfThreads, int msgs)
        {
            var timesCalled = 0;
            var mqHost      = CreateMqServer();

            mqHost.RegisterHandler <Wait>(m =>
            {
                Interlocked.Increment(ref timesCalled);
                Thread.Sleep(m.GetBody().ForMs);
                return(null);
            }, noOfThreads);

            mqHost.Start();

            var mqClient = mqHost.MessageFactory.CreateMessageQueueClient();

            var dto = new Wait
            {
                ForMs = 100
            };

            msgs.Times(i => mqClient.Publish(dto));

            SqsTestAssert.WaitUntilTrueOrTimeout(() => timesCalled >= msgs, timeoutSeconds: 12);

            mqHost.Dispose();

            Assert.That(timesCalled, Is.EqualTo(msgs));
        }
Beispiel #5
0
        public void Does_process_messages_sent_before_it_was_started()
        {
            var reverseCalled = 0;

            var mqHost = CreateMqServer();

            mqHost.RegisterHandler <Reverse>(x =>
            {
                Interlocked.Increment(ref reverseCalled);
                return(x.GetBody().Value.Reverse());
            });

            var mqClient = mqHost.MessageFactory.CreateMessageQueueClient();

            Publish_4_messages(mqClient);

            mqHost.Start();

            SqsTestAssert.WaitUntilTrueOrTimeout(() => reverseCalled >= 4, timeoutSeconds: 3);

            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(4));
            Assert.That(reverseCalled, Is.EqualTo(4));

            mqHost.Dispose();
        }
Beispiel #6
0
        public void Can_receive_and_process_same_reply_responses()
        {
            var called = 0;
            var mqHost = CreateMqServer();

            mqHost.RegisterHandler <Incr2>(m =>
            {
                Debug.WriteLine("In Incr #" + m.GetBody().Value);
                called++;
                return(m.GetBody().Value > 0
                    ? new Incr2 {
                    Value = m.GetBody().Value - 1
                }
                    : null);
            });

            mqHost.Start();

            var mqClient = mqHost.MessageFactory.CreateMessageQueueClient();

            var incr = new Incr2
            {
                Value = 5
            };

            mqClient.Publish(incr);

            SqsTestAssert.WaitUntilTrueOrTimeout(() => called >= incr.Value + 1);

            Assert.That(called, Is.EqualTo(1 + incr.Value));
        }
        public void Can_remove_empty_temp_queues()
        {
            //Clean up
            sqsQueueManager.RemoveEmptyTemporaryQueues(DateTime.UtcNow.AddDays(5).ToUnixTime());

            var nonEmptyTempQueue = sqsQueueManager.CreateQueue(QueueNames.GetTempQueueName());

            sqsQueueManager.SqsClient.SendMessage(new SendMessageRequest(nonEmptyTempQueue.QueueUrl, "Just some text"));
            sqsQueueManager.SqsClient.SendMessage(new SendMessageRequest(nonEmptyTempQueue.QueueUrl, "Just some more text"));

            var emptyTempQueue1         = sqsQueueManager.CreateQueue(QueueNames.GetTempQueueName());
            var emptyTempQueue2         = sqsQueueManager.CreateQueue(QueueNames.GetTempQueueName());
            var emptyTempQueueNotCached = sqsQueueManager.CreateQueue(QueueNames.GetTempQueueName());

            if (!SqsTestAssert.IsFakeClient)
            {   // List queue doesn't return newly created queues for a bit, so if this a "real", we skip this part
                sqsQueueManager.QueueNameMap.TryRemove(emptyTempQueueNotCached.QueueName, out _);
            }

            var countOfQueuesRemoved = sqsQueueManager.RemoveEmptyTemporaryQueues(DateTime.UtcNow.AddDays(5).ToUnixTime());

            try
            {
                SqsTestAssert.FakeEqualRealGreater(3, 2, countOfQueuesRemoved);
            }
            finally
            {
                // Cleanup
                sqsQueueManager.DeleteQueue(nonEmptyTempQueue.QueueName);
                sqsQueueManager.DeleteQueue(emptyTempQueue1.QueueName);
                sqsQueueManager.DeleteQueue(emptyTempQueue2.QueueName);
                sqsQueueManager.DeleteQueue(emptyTempQueueNotCached.QueueName);
            }
        }
Beispiel #8
0
        public void Receive_is_buffered_when_buffering_enabled_and_disposing_drains()
        {
            var buffer = GetNewMqBuffer();

            buffer.QueueDefinition.SendBufferSize = 1;

            10.Times(i =>
            {
                var sent = buffer.Send(new SendMessageRequest
                {
                    QueueUrl    = buffer.QueueDefinition.QueueUrl,
                    MessageBody = GetNewId()
                });

                Assert.IsTrue(sent);
                Assert.AreEqual(0, buffer.SendBufferCount);
            });

            // Using a real SQS queue results in the Receive being sporadic in terms of actually returning
            // a batch of stuff on a receive call, as it is dependent on the size of the queue, where you land,
            // etc., so in a real SQS scenario, allow a few attempts to the server to actually receive a batch
            // of data, which is the best we can do

            var timesToTry = SqsTestAssert.IsFakeClient
                ? 1
                : 10;

            var attempts = 0;

            Message received = null;

            while (attempts < timesToTry)
            {
                received = buffer.Receive(new ReceiveMessageRequest
                {
                    QueueUrl            = buffer.QueueDefinition.QueueUrl,
                    MaxNumberOfMessages = 10,
                    WaitTimeSeconds     = SqsTestAssert.IsFakeClient
                        ? 0
                        : SqsQueueDefinition.MaxWaitTimeSeconds,
                    VisibilityTimeout = SqsQueueDefinition.MaxVisibilityTimeoutSeconds
                });

                if (received != null && buffer.ReceiveBufferCount > 0)
                {
                    break;
                }

                attempts++;
            }

            Assert.IsNotNull(received);
            SqsTestAssert.FakeEqualRealGreater(9, 0, buffer.ReceiveBufferCount);

            buffer.Dispose();

            Assert.AreEqual(0, buffer.ReceiveBufferCount, "Dispose did not drain");
        }
Beispiel #9
0
        public void Deleting_from_non_existent_q_throws_exception()
        {
            var entries  = 1.Times(() => new DeleteMessageBatchRequestEntry());
            var queueUrl = $"http://{Guid.NewGuid():N}.com";

            SqsTestAssert.Throws <QueueDoesNotExistException>(() =>
                                                              client.DeleteMessageBatch(new DeleteMessageBatchRequest(queueUrl, entries)),
                                                              "specified queue does not exist");
        }
Beispiel #10
0
        public void Cannot_Stop_a_Disposed_MqHost()
        {
            var mqHost = CreateMqServer();

            mqHost.RegisterHandler <Reverse>(x => x.GetBody().Value.Reverse());
            mqHost.Start();

            SqsTestAssert.WaitUntilTrueOrTimeout(() =>
            {
                var status = mqHost.GetStatus();
                return(status != null && status.Equals("Started"));
            }, timeoutSeconds: 2);

            mqHost.Dispose();

            Assert.Throws <ObjectDisposedException>(mqHost.Stop);
        }
Beispiel #11
0
        public void Only_allows_1_BgThread_to_run_at_a_time()
        {
            var mqHost = CreateMqServer();

            mqHost.RegisterHandler <Reverse>(x => x.GetBody().Value.Reverse());
            mqHost.RegisterHandler <Rot13>(x => x.GetBody().Value.ToRot13());

            5.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));

            SqsTestAssert.WaitUntilTrueOrTimeout(() =>
            {
                var status = mqHost.GetStatus();
                return(status != null && status.Equals("Started"));
            }, timeoutSeconds: 1);

            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));
            Assert.That(mqHost.BgThreadCount, Is.EqualTo(1));

            10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Stop()));

            SqsTestAssert.WaitUntilTrueOrTimeout(() =>
            {
                var status = mqHost.GetStatus();
                return(status != null && status.Equals("Stopped"));
            }, timeoutSeconds: 1);

            Assert.That(mqHost.GetStatus(), Is.EqualTo("Stopped"));

            ThreadPool.QueueUserWorkItem(y => mqHost.Start());

            SqsTestAssert.WaitUntilTrueOrTimeout(() =>
            {
                var status = mqHost.GetStatus();
                return(status != null && status.Equals("Started"));
            }, timeoutSeconds: 1);

            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

            Assert.That(mqHost.BgThreadCount, Is.EqualTo(2));

            Debug.WriteLine(mqHost.GetStats());

            mqHost.Dispose();
        }
        public void Qd_does_not_return_for_non_existent_queue_that_is_already_cached_when_forced()
        {
            var qd = sqsQueueManager.CreateQueue(GetNewId());

            var returnedQd = sqsQueueManager.GetQueueDefinition(qd.QueueName);

            Assert.IsTrue(ReferenceEquals(qd, returnedQd));

            // delete q directly at the client
            Assert.IsNotNull(sqsQueueManager.SqsClient.DeleteQueue(new DeleteQueueRequest(qd.QueueUrl)));

            // should still be in the cache
            Assert.IsTrue(sqsQueueManager.QueueNameMap.ContainsKey(qd.QueueName));

            // should still return true when not forced, false when forced
            Assert.IsNotNull(sqsQueueManager.GetQueueDefinition(qd.QueueName));

            SqsTestAssert.Throws <QueueDoesNotExistException>(() => sqsQueueManager.GetQueueDefinition(qd.QueueName, forceRecheck: true), "specified queue does not exist");
        }
Beispiel #13
0
        public void Can_delete_batch_of_messages()
        {
            var newQueueUrl = helper.CreateQueue();

            helper.SendMessages(newQueueUrl, count: 6);

            var received = client.ReceiveMessage(new ReceiveMessageRequest
            {
                QueueUrl            = newQueueUrl,
                MaxNumberOfMessages = 5,
                VisibilityTimeout   = 30,
                WaitTimeSeconds     = 0
            });

            SqsTestAssert.FakeEqualRealGreater(5, 1, received.Messages.Count);

            var response = client.DeleteMessageBatch(new DeleteMessageBatchRequest(
                                                         newQueueUrl,
                                                         received.Messages.Select(m => new DeleteMessageBatchRequestEntry {
                Id            = m.MessageId,
                ReceiptHandle = m.ReceiptHandle
            }).ToList()
                                                         ));

            Assert.AreEqual(received.Messages.Count, response.Successful.Count);

            received = client.ReceiveMessage(new ReceiveMessageRequest
            {
                QueueUrl            = newQueueUrl,
                MaxNumberOfMessages = 5,
                VisibilityTimeout   = 30,
                WaitTimeSeconds     = 0
            });

            SqsTestAssert.FakeEqualRealGreater(1, 0, received.Messages.Count);
        }
Beispiel #14
0
        public void Sending_to_non_existent_q_throws_exception()
        {
            var queueUrl = $"http://{Guid.NewGuid():N}.com";

            SqsTestAssert.Throws <QueueDoesNotExistException>(() => helper.SendMessages(queueUrl), "specified queue does not exist");
        }
Beispiel #15
0
        public void Does_retry_messages_with_errors_by_RetryCount()
        {
            const int retryCount   = 1;
            const int totalRetries = 1 + retryCount;

            var mqHost = CreateMqServer(retryCount);

            var reverseCalled      = 0;
            var rot13Called        = 0;
            var alwaysThrowsCalled = 0;

            mqHost.RegisterHandler <Reverse>(x =>
            {
                Interlocked.Increment(ref reverseCalled);
                return(x.GetBody().Value.Reverse());
            });
            mqHost.RegisterHandler <Rot13>(x =>
            {
                Interlocked.Increment(ref rot13Called);
                return(x.GetBody().Value.ToRot13());
            });
            mqHost.RegisterHandler <AlwaysThrows>(x =>
            {
                Interlocked.Increment(ref alwaysThrowsCalled);
                throw new Exception("Always Throwing! " + x.GetBody().Value);
            });

            mqHost.Start();

            var mqClient = mqHost.MessageFactory.CreateMessageQueueClient();

            mqClient.Publish(new AlwaysThrows
            {
                Value = "1st"
            });
            mqClient.Publish(new Reverse
            {
                Value = "Hello"
            });
            mqClient.Publish(new Reverse
            {
                Value = "World"
            });
            mqClient.Publish(new Rot13
            {
                Value = "ServiceStack"
            });

            SqsTestAssert.WaitUntilTrueOrTimeout(() => reverseCalled >= 2 && rot13Called >= 1 && alwaysThrowsCalled >= 1);

            Assert.That(mqHost.GetStats().TotalMessagesFailed, Is.EqualTo(1 * totalRetries));
            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(2 + 1));

            5.Times(x => mqClient.Publish(new AlwaysThrows
            {
                Value = "#" + x
            }));

            mqClient.Publish(new Reverse
            {
                Value = "Hello"
            });
            mqClient.Publish(new Reverse
            {
                Value = "World"
            });
            mqClient.Publish(new Rot13
            {
                Value = "ServiceStack"
            });

            SqsTestAssert.WaitUntilTrueOrTimeout(() => reverseCalled >= 4 && rot13Called >= 2 && alwaysThrowsCalled >= 6, timeoutSeconds: 5);

            Debug.WriteLine(mqHost.GetStatsDescription());

            Assert.That(mqHost.GetStats().TotalMessagesFailed, Is.EqualTo((1 + 5) * totalRetries));
            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(6));

            Assert.That(reverseCalled, Is.EqualTo(2 + 2));
            Assert.That(rot13Called, Is.EqualTo(1 + 1));
        }
Beispiel #16
0
        public void Does_process_all_messages_and_Starts_Stops_correctly_with_multiple_threads_racing()
        {
            var mqHost = CreateMqServer();

            var reverseCalled = 0;
            var rot13Called   = 0;

            mqHost.RegisterHandler <Reverse>(x =>
            {
                Interlocked.Increment(ref reverseCalled);
                "Processing Reverse {0}...".Print(reverseCalled);
                return(x.GetBody().Value.Reverse());
            });
            mqHost.RegisterHandler <Rot13>(x =>
            {
                Interlocked.Increment(ref rot13Called);
                "Processing Rot13 {0}...".Print(rot13Called);
                return(x.GetBody().Value.ToRot13());
            });

            var mqClient = mqHost.MessageFactory.CreateMessageQueueClient();

            mqClient.Publish(new Reverse
            {
                Value = "Hello"
            });
            mqClient.Publish(new Reverse
            {
                Value = "World"
            });
            mqClient.Publish(new Rot13
            {
                Value = "ServiceStack"
            });

            mqHost.Start();

            SqsTestAssert.WaitUntilTrueOrTimeout(() => reverseCalled >= 2 && rot13Called >= 1, timeoutSeconds: 4);

            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));
            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(3));

            mqClient.Publish(new Reverse
            {
                Value = "Foo"
            });
            mqClient.Publish(new Rot13
            {
                Value = "Bar"
            });

            10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));
            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

            5.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Stop()));

            SqsTestAssert.WaitUntilTrueOrTimeout(() =>
            {
                var status = mqHost.GetStatus();
                return(status != null && status.Equals("Stopped"));
            }, timeoutSeconds: 2);

            Assert.That(mqHost.GetStatus(), Is.EqualTo("Stopped"));

            10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));

            SqsTestAssert.WaitUntilTrueOrTimeout(() =>
            {
                var status = mqHost.GetStatus();
                return(reverseCalled >= 3 && rot13Called >= 2 && status != null && status.Equals("Started"));
            }, timeoutSeconds: 4);

            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

            Debug.WriteLine("\n" + mqHost.GetStats());

            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(5));
            Assert.That(reverseCalled, Is.EqualTo(3));
            Assert.That(rot13Called, Is.EqualTo(2));

            mqHost.Dispose();
        }