Beispiel #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));
        }
Beispiel #2
0
        public void EmptyTopicMetadataShouldThrowException()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter();

            Assert.Throws <RoutingException>(() => router.GetTopicMetadata("MissingTopic"));
        }
Beispiel #3
0
 private void CreateSuccessfulSendMock(RoutingScenario router)
 {
     router.Connection1.Add(ApiKey.Fetch, ShouldReturnValidMessage);
     router.Connection1.Add(ApiKey.Metadata, async _ => await RoutingScenario.DefaultMetadataResponse());
     router.Connection2.Add(ApiKey.Fetch, ShouldReturnValidMessage);
     router.Connection2.Add(ApiKey.Metadata, async _ => await RoutingScenario.DefaultMetadataResponse());
 }
Beispiel #4
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));
        }
Beispiel #5
0
        public async Task GetGroupShouldThrowWhenServerCollectionIsEmpty()
        {
            var scenario = new RoutingScenario();
            var router   = scenario.CreateRouter();

            Assert.Throws <RoutingException>(() => router.GetGroupConnection("unknown"));
        }
Beispiel #6
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));
        }
Beispiel #7
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.");
            }
        }
Beispiel #8
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.");
            }
        }
Beispiel #9
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));
            }
        }
Beispiel #10
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));
        }
Beispiel #11
0
        public void ProducerShouldInterruptWaitOnEmptyCollection()
        {
            //use the fake to actually cause loop to execute
            var router = new RoutingScenario().CreateRouter();

            var producer = new Producer(router);

            using (producer) { }
        }
Beispiel #12
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));
        }
Beispiel #13
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));
        }
Beispiel #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)");
        }
Beispiel #15
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"));
        }
Beispiel #16
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));
        }
Beispiel #17
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));
        }
Beispiel #18
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));
        }
Beispiel #19
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);
        }
Beispiel #20
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));
        }
Beispiel #21
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));
        }
Beispiel #22
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));
        }
Beispiel #23
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));
        }
Beispiel #24
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));
        }
Beispiel #25
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));
        }
Beispiel #26
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));
        }
Beispiel #27
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));
        }
Beispiel #28
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));
        }
Beispiel #29
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));
        }
Beispiel #30
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));
        }