Пример #1
0
        public async Task SelectShouldChange()
        {
            var scenario = new RoutingScenario();

            var cacheExpiry = TimeSpan.FromMilliseconds(1);
            var router      = scenario.CreateRouter(cacheExpiry);

            scenario.MetadataResponse = RoutingScenario.DefaultMetadataResponse;
            var testTopic = RoutingScenario.TestTopic;
            await router.RefreshTopicMetadataAsync(testTopic, true, CancellationToken.None);

            var router1 = router.GetTopicConnection(testTopic, 0);

            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(1));
            await Task.Delay(cacheExpiry.Add(TimeSpan.FromMilliseconds(1))); // After cache is expired

            scenario.MetadataResponse = RoutingScenario.MetadataResponseWithSingleBroker;
            await router.RefreshTopicMetadataAsync(testTopic, true, CancellationToken.None);

            var router2 = router.GetTopicConnection(testTopic, 0);

            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(2));
            Assert.That(router1.Connection.Endpoint, Is.EqualTo(scenario.Connection1.Endpoint));
            Assert.That(router2.Connection.Endpoint, Is.EqualTo(scenario.Connection2.Endpoint));
            Assert.That(router1.Connection.Endpoint, Is.Not.EqualTo(router2.Connection.Endpoint));
        }
Пример #2
0
        public void EmptyTopicMetadataShouldThrowException()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter();

            Assert.Throws <RoutingException>(() => router.GetTopicMetadata("MissingTopic"));
        }
Пример #3
0
        public async Task ShouldUpdateMetadataOnce()
        {
            var scenario        = new RoutingScenario();
            var cacheExpiration = TimeSpan.FromMilliseconds(100);
            var router          = scenario.CreateRouter(cacheExpiration);

            scenario.Connection1.Add(ApiKey.Fetch, ShouldReturnValidMessage);
            scenario.Connection1.Add(ApiKey.Metadata, async _ => await RoutingScenario.DefaultMetadataResponse());
            int numberOfCall = 1000;

            Task[] tasks = new Task[numberOfCall];
            for (int i = 0; i < numberOfCall / 2; i++)
            {
                tasks[i] = router.SendAsync(new FetchRequest(), RoutingScenario.TestTopic, 0, CancellationToken.None);
            }
            await Task.Delay(cacheExpiration);

            await Task.Delay(1);

            for (int i = 0; i < numberOfCall / 2; i++)
            {
                tasks[i + numberOfCall / 2] = router.SendAsync(new FetchRequest(), RoutingScenario.TestTopic, 0, CancellationToken.None);
            }

            await Task.WhenAll(tasks);

            Assert.That(scenario.Connection1[ApiKey.Fetch], Is.EqualTo(numberOfCall));
            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(1));
        }
Пример #4
0
        public async Task GetGroupShouldThrowWhenServerCollectionIsEmpty()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter();

            Assert.Throws <RoutingException>(() => router.GetGroupConnection("unknown"));
        }
Пример #5
0
        public async Task ShouldRecoverUpdateMetadataForNewTopic()
        {
            var scenario        = new RoutingScenario();
            var cacheExpiration = TimeSpan.FromMilliseconds(100);
            var router          = scenario.CreateRouter(cacheExpiration);

            var fetchRequest = new FetchRequest();

            scenario.Connection1.Add(ApiKey.Fetch, ShouldReturnValidMessage);
            scenario.Connection1.Add(ApiKey.Metadata, async _ => await RoutingScenario.DefaultMetadataResponse());
            int numberOfCall = 100;

            Task[] tasks = new Task[numberOfCall];
            for (int i = 0; i < numberOfCall / 2; i++)
            {
                tasks[i] = router.SendAsync(fetchRequest, RoutingScenario.TestTopic, 0, CancellationToken.None);
            }

            scenario.Connection1.Add(ApiKey.Metadata, async _ => {
                var response = await RoutingScenario.DefaultMetadataResponse();
                return(new MetadataResponse(response.brokers, response.topic_metadata.Select(t => new MetadataResponse.Topic("test2", t.topic_error_code, t.partition_metadata))));
            });

            for (int i = 0; i < numberOfCall / 2; i++)
            {
                tasks[i + numberOfCall / 2] = router.SendAsync(fetchRequest, "test2", 0, CancellationToken.None);
            }

            await Task.WhenAll(tasks);

            Assert.That(scenario.Connection1[ApiKey.Fetch], Is.EqualTo(numberOfCall));
            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(2));
        }
Пример #6
0
        public async Task ProducerShouldReportCorrectNumberOfAsyncRequests()
        {
            var semaphore = new SemaphoreSlim(0);
            var scenario  = new RoutingScenario();

            //block the second call returning from send message async
            scenario.Connection1.Add(ApiKey.Produce, async _ =>
            {
                await semaphore.WaitAsync();
                return(new ProduceResponse());
            });

            var router = scenario.CreateRouter();

            using (var producer = new Producer(router, new ProducerConfiguration(requestParallelization: 1, batchSize: 1)))
            {
                var messages = new[] { new Message("1") };

                Assert.That(producer.ActiveSenders, Is.EqualTo(0));

                var sendTask = producer.SendAsync(messages, RoutingScenario.TestTopic, CancellationToken.None);

                await AssertAsync.ThatEventually(() => producer.ActiveSenders >= 1, () => $"senders {producer.ActiveSenders}");

                semaphore.Release();
                await Task.WhenAny(sendTask, Task.Delay(2500));

                Assert.That(sendTask.IsCompleted, Is.True, "Send task should be marked as completed.");
                Assert.That(producer.ActiveSenders, Is.EqualTo(0), "Async should now show zero count.");
            }
        }
Пример #7
0
        //someTime failed
        public async Task ProducerShouldBlockWhenFullBufferReached()
        {
            int count = 0;
            //with max buffer set below the batch size, this should cause the producer to block until batch delay time.
            var scenario = new RoutingScenario();

            scenario.Connection1.Add(ApiKey.Produce, async _ => {
                await Task.Delay(200);
                return(new ProduceResponse());
            });
            using (var producer = new Producer(scenario.CreateRouter(), new ProducerConfiguration(batchSize: 10, batchMaxDelay: TimeSpan.FromMilliseconds(500))))
            {
                var senderTask = Task.Factory.StartNew(async() => {
                    for (int i = 0; i < 3; i++)
                    {
                        await producer.SendAsync(new Message(i.ToString()), RoutingScenario.TestTopic, CancellationToken.None);
                        TestConfig.Log.Info(() => LogEvent.Create($"Buffered {producer.BufferedMessageCount}, In Flight: {producer.InFlightMessageCount}"));
                        Interlocked.Increment(ref count);
                    }
                });

                await AssertAsync.ThatEventually(() => count > 0 && producer.BufferedMessageCount == 1, () => $"buffered {producer.BufferedMessageCount}, count {count}");

                TestConfig.Log.Info(() => LogEvent.Create("Waiting for the rest..."));
                await Task.WhenAny(senderTask, Task.Delay(5000));

                Assert.That(senderTask.IsCompleted);
                Assert.That(producer.BufferedMessageCount, Is.EqualTo(1), "One message should be left in the buffer.");
            }
        }
Пример #8
0
        public async Task ProducesShouldSendOneProduceRequestForEachBatchSize()
        {
            var scenario = new RoutingScenario();
            var producer = new Producer(scenario.CreateRouter(), new ProducerConfiguration(batchSize: 4));

            using (producer)
            {
                var calls = new[]
                {
                    producer.SendAsync(new Message("1"), RoutingScenario.TestTopic, CancellationToken.None),
                    producer.SendAsync(new Message("2"), RoutingScenario.TestTopic, CancellationToken.None),
                    producer.SendAsync(new Message("3"), RoutingScenario.TestTopic, CancellationToken.None),
                    producer.SendAsync(new Message("4"), RoutingScenario.TestTopic, CancellationToken.None),
                    producer.SendAsync(new Message("5"), RoutingScenario.TestTopic, CancellationToken.None),
                    producer.SendAsync(new Message("6"), RoutingScenario.TestTopic, CancellationToken.None),
                    producer.SendAsync(new Message("7"), RoutingScenario.TestTopic, CancellationToken.None),
                    producer.SendAsync(new Message("8"), RoutingScenario.TestTopic, CancellationToken.None)
                };

                await Task.WhenAll(calls);

                Assert.That(scenario.Connection1[ApiKey.Produce], Is.EqualTo(2));
                Assert.That(scenario.Connection2[ApiKey.Produce], Is.EqualTo(2));
            }
        }
Пример #9
0
        public async Task SelectExactPartitionShouldThrowWhenPartitionDoesNotExist()
        {
            var scenario  = new RoutingScenario();
            var router    = scenario.CreateRouter();
            var testTopic = RoutingScenario.TestTopic;
            await router.GetTopicMetadataAsync(testTopic, CancellationToken.None);

            Assert.Throws <RoutingException>(() => router.GetTopicConnection(testTopic, 3));
        }
Пример #10
0
        public async Task GetTopicShouldReturnTopic()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter();
            await router.GetTopicMetadataAsync(RoutingScenario.TestTopic, CancellationToken.None);

            var result = router.GetTopicMetadata(RoutingScenario.TestTopic);

            Assert.That(result.topic, Is.EqualTo(RoutingScenario.TestTopic));
        }
Пример #11
0
        public async Task SendProtocolRequestShouldThrowException(Type exceptionType)
        {
            var scenario        = new RoutingScenario();
            var cacheExpiration = TimeSpan.FromMilliseconds(10);
            var router          = scenario.CreateRouter(cacheExpiration);

            scenario.Connection1.Add(ApiKey.Fetch, FailedInFirstMessageException(exceptionType, cacheExpiration));
            scenario.Connection1.Add(ApiKey.Metadata, async _ => await RoutingScenario.DefaultMetadataResponse());
            Assert.ThrowsAsync(exceptionType, async() => await router.SendAsync(new FetchRequest(), RoutingScenario.TestTopic, 0, CancellationToken.None));
        }
Пример #12
0
        public async Task SendProtocolRequestShouldNotTryToRefreshMataDataIfCanNotRecoverByRefreshMetadata(
            ErrorCode code)
        {
            var scenario        = new RoutingScenario();
            var cacheExpiration = TimeSpan.FromMilliseconds(10);
            var router          = scenario.CreateRouter(cacheExpiration);

            scenario.Connection1.Add(ApiKey.Fetch, FailedInFirstMessageError(code, cacheExpiration));
            scenario.Connection1.Add(ApiKey.Metadata, async _ => await RoutingScenario.DefaultMetadataResponse());
            Assert.ThrowsAsync <RequestException>(async() => await router.SendAsync(new FetchRequest(), RoutingScenario.TestTopic, 0, CancellationToken.None));
        }
Пример #13
0
        public async Task GetTopicOffsetsShouldQueryEachServer()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter();

            var results = await router.GetOffsetsAsync(RoutingScenario.TestTopic, 2, -1, CancellationToken.None);

            Assert.That(scenario.Connection1[ApiKey.Offsets], Is.EqualTo(1));
            Assert.That(scenario.Connection2[ApiKey.Offsets], Is.EqualTo(1));
            Assert.That(results.Count, Is.EqualTo(2));
        }
Пример #14
0
        public async Task ShouldRecoverFromFailureByUpdateMetadataOnce() //Do not debug this test !!
        {
            var scenario        = new RoutingScenario();
            var cacheExpiration = TimeSpan.FromMilliseconds(1000);
            var router          = scenario.CreateRouter(cacheExpiration);

            int partitionId  = 0;
            var fetchRequest = new FetchRequest();

            int  numberOfCall            = 100;
            long numberOfErrorSend       = 0;
            TaskCompletionSource <int> x = new TaskCompletionSource <int>();
            Func <IRequestContext, Task <IResponse> > ShouldReturnNotLeaderForPartitionAndThenNoError = async _ =>
            {
                var log = TestConfig.Log;
                log.Debug(() => LogEvent.Create("FetchResponse Start "));
                if (!x.Task.IsCompleted)
                {
                    if (Interlocked.Increment(ref numberOfErrorSend) == numberOfCall)
                    {
                        await Task.Delay(cacheExpiration);

                        await Task.Delay(1);

                        x.TrySetResult(1);
                        log.Debug(() => LogEvent.Create("all is complete "));
                    }

                    await x.Task;
                    log.Debug(() => LogEvent.Create("SocketException "));
                    throw new ConnectionException(scenario.Connection1.Endpoint);
                }
                log.Debug(() => LogEvent.Create("Completed "));

                return(new FetchResponse());
            };

            scenario.Connection1.Add(ApiKey.Fetch, ShouldReturnNotLeaderForPartitionAndThenNoError);
            scenario.Connection1.Add(ApiKey.Metadata, async _ => await RoutingScenario.DefaultMetadataResponse());

            Task[] tasks = new Task[numberOfCall];

            for (int i = 0; i < numberOfCall; i++)
            {
                tasks[i] = router.SendAsync(fetchRequest, RoutingScenario.TestTopic, partitionId, CancellationToken.None);
            }

            await Task.WhenAll(tasks);

            Assert.That(numberOfErrorSend, Is.GreaterThan(1), "numberOfErrorSend");
            Assert.That(scenario.Connection1[ApiKey.Fetch], Is.EqualTo(numberOfCall + numberOfErrorSend),
                        "RequestCallCount(ApiKey.Fetch)");
            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(2), "RequestCallCount(ApiKey.Metadata)");
        }
Пример #15
0
        public async Task ShouldThrowNoLeaderElectedForPartition()
        {
            var scenario = new RoutingScenario {
                MetadataResponse = RoutingScenario.MetadataResponseWithNotEndToElectLeader
            };

            var router = scenario.CreateRouter();
            await AssertAsync.Throws <RoutingException>(() => router.GetTopicMetadataAsync(RoutingScenario.TestTopic, CancellationToken.None));

            Assert.AreEqual(0, router.GetTopicMetadata().Count);
        }
Пример #16
0
        public async Task GetGroupOffsetsShouldThrowAnyException()
        {
            var scenario = new RoutingScenario();

            scenario.Connection1.Add(ApiKey.OffsetFetch, _ => { throw new BufferUnderRunException("test 99"); });
            var router = scenario.CreateRouter();

            await AssertAsync.Throws <BufferUnderRunException>(
                () => router.GetOffsetsAsync(RoutingScenario.TestGroup, RoutingScenario.TestTopic, CancellationToken.None),
                ex => ex.Message.Contains("test 99"));
        }
Пример #17
0
        public async Task RefreshAllTopicMetadataShouldAlwaysDoRequest()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter();
            await router.RefreshTopicMetadataAsync(CancellationToken.None);

            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(1));
            await router.RefreshTopicMetadataAsync(CancellationToken.None);

            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(2));
        }
Пример #18
0
        public async Task SimultaneouslyRefreshGroupMetadataShouldNotGetDataFromCacheOnSameRequest()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter();

            var testTopic = RoutingScenario.TestTopic;
            await Task.WhenAll(
                router.RefreshGroupConnectionAsync(testTopic, true, CancellationToken.None),
                router.RefreshGroupConnectionAsync(testTopic, true, CancellationToken.None));

            Assert.That(scenario.Connection1[ApiKey.GroupCoordinator], Is.EqualTo(2));
        }
Пример #19
0
        public async Task SimultaneouslyGetGroupMetadataShouldGetDataFromCacheOnSameRequest()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter(TimeSpan.FromMinutes(1)); // long timeout to avoid race condition on lock lasting longer than cache timeout

            var testTopic = RoutingScenario.TestTopic;
            await Task.WhenAll(
                router.GetGroupConnectionAsync(testTopic, CancellationToken.None),
                router.GetGroupConnectionAsync(testTopic, CancellationToken.None));

            Assert.That(scenario.Connection1[ApiKey.GroupCoordinator], Is.EqualTo(1));
        }
Пример #20
0
        public async Task ShouldThrowIfCycleCouldNotConnectToAnyServerForGroup()
        {
            var scenario = new RoutingScenario();

            scenario.Connection1.Add(ApiKey.GroupCoordinator, _ => { throw new Exception("some error"); });
            scenario.Connection2.Add(ApiKey.GroupCoordinator, _ => { throw new Exception("some error"); });
            var router = scenario.CreateRouter();

            Assert.ThrowsAsync <RoutingException>(async() => await router.GetGroupConnectionAsync(RoutingScenario.TestTopic, CancellationToken.None));

            Assert.That(scenario.Connection1[ApiKey.GroupCoordinator], Is.EqualTo(1));
            Assert.That(scenario.Connection2[ApiKey.GroupCoordinator], Is.EqualTo(1));
        }
Пример #21
0
        public async Task SelectExactPartitionShouldReturnRequestedPartition()
        {
            var scenario  = new RoutingScenario();
            var router    = scenario.CreateRouter();
            var testTopic = RoutingScenario.TestTopic;
            await router.GetTopicMetadataAsync(testTopic, CancellationToken.None);

            var p0 = router.GetTopicConnection(testTopic, 0);
            var p1 = router.GetTopicConnection(testTopic, 1);

            Assert.That(p0.PartitionId, Is.EqualTo(0));
            Assert.That(p1.PartitionId, Is.EqualTo(1));
        }
Пример #22
0
        public async Task SelectExactPartitionShouldThrowWhenTopicsCollectionIsEmpty()
        {
            var metadataResponse = await RoutingScenario.DefaultMetadataResponse();

            metadataResponse.topic_metadata.Clear();

            var scenario = new RoutingScenario();

#pragma warning disable 1998
            scenario.Connection1.Add(ApiKey.Metadata, async _ => metadataResponse);
#pragma warning restore 1998

            Assert.Throws <RoutingException>(() => scenario.CreateRouter().GetTopicConnection(RoutingScenario.TestTopic, 1));
        }
Пример #23
0
        public async Task ShouldReturnGroupFromCache()
        {
            var scenario  = new RoutingScenario();
            var router    = scenario.CreateRouter();
            var testTopic = RoutingScenario.TestTopic;
            await router.GetGroupConnectionAsync(testTopic, CancellationToken.None);

            var result1 = router.GetGroupConnection(testTopic);
            var result2 = router.GetGroupConnection(testTopic);

            Assert.That(scenario.Connection1[ApiKey.GroupCoordinator], Is.EqualTo(1));
            Assert.That(result1.GroupId, Is.EqualTo(testTopic));
            Assert.That(result2.GroupId, Is.EqualTo(testTopic));
        }
Пример #24
0
        public async Task ShouldTryToRefreshMataDataIfOnExceptions(Type exceptionType)
        {
            var scenario        = new RoutingScenario();
            var cacheExpiration = TimeSpan.FromMilliseconds(10);
            var router          = scenario.CreateRouter(cacheExpiration);

            scenario.Connection1.Add(ApiKey.Fetch, FailedInFirstMessageException(exceptionType, cacheExpiration));
            scenario.Connection1.Add(ApiKey.Metadata, async _ => await RoutingScenario.DefaultMetadataResponse());

            await router.SendAsync(new FetchRequest(), RoutingScenario.TestTopic, 0, CancellationToken.None);

            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(2));
            Assert.That(scenario.Connection1[ApiKey.Fetch], Is.EqualTo(2));
        }
Пример #25
0
        public async Task ShouldThrowIfCycleCouldNotConnectToAnyServer()
        {
            var scenario = new RoutingScenario();

            scenario.Connection1.Add(ApiKey.Metadata, _ => { throw new ConnectionException("some error"); });
            scenario.Connection2.Add(ApiKey.Metadata, _ => { throw new ConnectionException("some error"); });
            var router = scenario.CreateRouter();

            await AssertAsync.Throws <ConnectionException>(() => router.GetTopicMetadataAsync(RoutingScenario.TestTopic, CancellationToken.None));

            // 3 attempts total, round robin so 2 to connection1, 1 to connection2
            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(2));
            Assert.That(scenario.Connection2[ApiKey.Metadata], Is.EqualTo(1));
        }
Пример #26
0
        public async Task ShouldCycleThroughEachServerUntilOneIsFound()
        {
            var scenario = new RoutingScenario();

            scenario.Connection1.Add(ApiKey.Metadata, _ => { throw new Exception("some error"); });
            var router    = scenario.CreateRouter();
            var testTopic = RoutingScenario.TestTopic;
            await router.GetTopicMetadataAsync(testTopic, CancellationToken.None);

            var result = router.GetTopicMetadata(testTopic);

            Assert.That(result, Is.Not.Null);
            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(1));
            Assert.That(scenario.Connection2[ApiKey.Metadata], Is.EqualTo(1));
        }
Пример #27
0
        public async Task SimultaneouslyRefreshTopicsMetadataShouldNotGetDataFromCacheOnSameRequest()
        {
            var scenario = new RoutingScenario {
                MetadataResponse = RoutingScenario.MetadataResponseWithTwoTopics
            };
            var router = scenario.CreateRouter();

            var testTopics = new [] { RoutingScenario.TestTopic, RoutingScenario.TestTopic2 };
            await Task.WhenAll(
                router.RefreshTopicMetadataAsync(testTopics, true, CancellationToken.None),
                router.RefreshTopicMetadataAsync(testTopics, true, CancellationToken.None)
                ); //do not debug

            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(2));
        }
Пример #28
0
        public async Task RefreshTopicMetadataShouldIgnoreCacheAndAlwaysCauseMetadataRequestAfterExpirationDate()
        {
            var scenario        = new RoutingScenario();
            var cacheExpiration = TimeSpan.FromMilliseconds(100);
            var router          = scenario.CreateRouter(cacheExpiration);
            var testTopic       = RoutingScenario.TestTopic;
            await router.RefreshTopicMetadataAsync(testTopic, true, CancellationToken.None);

            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(1));
            await Task.Delay(cacheExpiration.Add(TimeSpan.FromMilliseconds(1))); // After cache is expired

            await router.RefreshTopicMetadataAsync(testTopic, true, CancellationToken.None);

            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(2));
        }
Пример #29
0
        public async Task ShouldReturnTopicFromCache()
        {
            var scenario  = new RoutingScenario();
            var router    = scenario.CreateRouter();
            var testTopic = RoutingScenario.TestTopic;
            await router.GetTopicMetadataAsync(testTopic, CancellationToken.None);

            var result1 = router.GetTopicMetadata(testTopic);
            var result2 = router.GetTopicMetadata(testTopic);

            Assert.AreEqual(1, router.GetTopicMetadata().Count);
            Assert.That(scenario.Connection1[ApiKey.Metadata], Is.EqualTo(1));
            Assert.That(result1.topic, Is.EqualTo(testTopic));
            Assert.That(result2.topic, Is.EqualTo(testTopic));
        }
Пример #30
0
        public async Task SelectExactPartitionShouldThrowWhenServerCollectionIsEmpty()
        {
            var metadataResponse = await RoutingScenario.DefaultMetadataResponse();

            metadataResponse = new MetadataResponse(topics: metadataResponse.topic_metadata);

            var scenario = new RoutingScenario();

#pragma warning disable 1998
            scenario.Connection1.Add(ApiKey.Metadata, async _ => metadataResponse);
#pragma warning restore 1998
            var router    = scenario.CreateRouter();
            var testTopic = RoutingScenario.TestTopic;
            await router.GetTopicMetadataAsync(testTopic, CancellationToken.None);

            Assert.Throws <RoutingException>(() => router.GetTopicConnection(testTopic, 1));
        }