public void ReadShouldLogDisconnectAndRecover() { var mockLog = _kernel.GetMock <IKafkaLog>(); using (var server = new FakeTcpServer(8999)) using (var socket = new KafkaTcpSocket(mockLog.Object, _kafkaEndpoint)) using (var conn = new KafkaConnection(socket, log: mockLog.Object)) { TaskTest.WaitFor(() => server.ConnectionEventcount > 0); Assert.That(server.ConnectionEventcount, Is.EqualTo(1)); server.DropConnection(); TaskTest.WaitFor(() => server.DisconnectionEventCount > 0); Assert.That(server.DisconnectionEventCount, Is.EqualTo(1)); //Wait a while for the client to notice the disconnect and log Thread.Sleep(15); //should log an exception and keep going mockLog.Verify(x => x.ErrorFormat(It.IsAny <string>(), It.IsAny <Exception>())); TaskTest.WaitFor(() => server.ConnectionEventcount > 1); Assert.That(server.ConnectionEventcount, Is.EqualTo(2)); } }
[Test, Repeat(1)]/// [Test, Repeat(100)] public async Task ReadShouldLogDisconnectAndRecover() { var mockLog = _kernel.GetMock <IKafkaLog>(); using (var server = new FakeTcpServer(_log, 8999)) using (var socket = new KafkaTcpSocket(mockLog.Object, _kafkaEndpoint, _maxRetry)) using (var conn = new KafkaConnection(socket, log: mockLog.Object)) { var disconnected = false; socket.OnServerDisconnected += () => disconnected = true; await TaskTest.WaitFor(() => server.ConnectionEventcount > 0); Assert.That(server.ConnectionEventcount, Is.EqualTo(1)); server.DropConnection(); await TaskTest.WaitFor(() => server.DisconnectionEventCount > 0); Assert.That(server.DisconnectionEventCount, Is.EqualTo(1)); //Wait a while for the client to notice the disconnect and log await TaskTest.WaitFor(() => disconnected); //should log an exception and keep going mockLog.Verify(x => x.ErrorFormat(It.IsAny <string>(), It.IsAny <Exception>())); await TaskTest.WaitFor(() => server.ConnectionEventcount > 1); Assert.That(server.ConnectionEventcount, Is.EqualTo(2)); } }
public void WriteShouldHandleLargeVolumeSendAsynchronously() { AutoResetEvent allEventAreArrived = new AutoResetEvent(false); var write = new ConcurrentBag <int>(); int percent = 0; using (var server = new FakeTcpServer(_log, FakeServerPort)) using (var test = new KafkaTcpSocket(new DefaultTraceLog(LogLevel.Warn), _fakeServerUrl, _maxRetry)) { int numberOfWrite = 10000; server.OnBytesReceived += data => { var d = data.Batch(4).Select(x => x.ToArray().ToInt32()); foreach (var item in d) { write.Add(item); } if (write.Count % (numberOfWrite / 100) == 0) { Console.WriteLine("*************** done percent:" + percent); percent++; } if (write.Count == numberOfWrite) { allEventAreArrived.Set(); } }; var tasks = Enumerable.Range(1, 10000).SelectMany(i => new[] { test.WriteAsync(i.ToBytes().ToPayload()), }).ToArray(); Task.WaitAll(tasks); Assert.IsTrue(allEventAreArrived.WaitOne(2000), "not get all event on time"); Assert.That(write.OrderBy(x => x), Is.EqualTo(Enumerable.Range(1, numberOfWrite))); } }
public async Task WriteShouldCancelWhileSendingData() { var writeAttempts = 0; using (var server = new FakeTcpServer(_log, FakeServerPort)) using (var test = new KafkaTcpSocket(_log, _fakeServerUrl, _maxRetry)) using (var token = new CancellationTokenSource()) { test.OnWriteToSocketAttempt += payload => Interlocked.Increment(ref writeAttempts); test.WriteAsync(new KafkaDataPayload { Buffer = 1.ToBytes() }, token.Token); await TaskTest.WaitFor(() => server.ConnectionEventcount > 0); await TaskTest.WaitFor(() => writeAttempts > 0); Assert.That(writeAttempts, Is.EqualTo(1), "Socket should have attempted to write."); //create a buffer write that will take a long time var data = Enumerable.Range(0, 100000000).Select(b => (byte)b).ToArray(); token.Cancel(); var taskResult = test.WriteAsync( new KafkaDataPayload { Buffer = data }, token.Token); await Task.WhenAny(taskResult, Task.Delay(TimeSpan.FromSeconds(5))).ConfigureAwait(false); Assert.That(taskResult.IsCanceled, Is.True, "Task should have cancelled."); } }
public void WriteAndReadShouldBeAsyncronous() { var write = new List <int>(); var read = new List <int>(); var expected = new List <int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; using (var server = new FakeTcpServer(FakeServerPort)) { server.OnBytesReceived += data => write.AddRange(data.Batch(4).Select(x => x.ToArray().ToInt32())); var test = new KafkaTcpSocket(new DefaultTraceLog(), _fakeServerUrl); var tasks = Enumerable.Range(1, 10) .SelectMany(i => new[] { test.WriteAsync(i.ToBytes()), test.ReadAsync(4).ContinueWith(t => read.Add(t.Result.ToInt32())), server.SendDataAsync(i.ToBytes()) }).ToArray(); Task.WaitAll(tasks); Assert.That(write.OrderBy(x => x), Is.EqualTo(expected)); Assert.That(read.OrderBy(x => x), Is.EqualTo(expected)); } }
public async void SendAsyncShouldNotAllowResponseToTimeoutWhileAwaitingKafkaToEstableConnection() { using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint)) using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(1000000), log: _log)) { Console.WriteLine("SendAsync blocked by reconnection attempts..."); var taskResult = conn.SendAsync(new MetadataRequest()); taskResult.ContinueWith(t => taskResult = t).Wait(TimeSpan.FromSeconds(1)); Console.WriteLine("Task result should be WaitingForActivation..."); Assert.That(taskResult.IsFaulted, Is.False); Assert.That(taskResult.Status, Is.EqualTo(TaskStatus.WaitingForActivation)); Console.WriteLine("Starting server to establish connection..."); using (var server = new FakeTcpServer(8999)) { server.OnClientConnected += () => Console.WriteLine("Client connected..."); server.OnBytesReceived += (b) => { server.SendDataAsync(MessageHelper.CreateMetadataResponse(1, "Test")); }; await taskResult; Assert.That(taskResult.IsFaulted, Is.False); Assert.That(taskResult.IsCanceled, Is.False); Assert.That(taskResult.Status, Is.EqualTo(TaskStatus.RanToCompletion)); } } }
public void ReadShouldReconnectAfterLosingConnection() { using (var server = new FakeTcpServer(FakeServerPort)) { var disconnects = 0; var connects = 0; server.OnClientConnected += () => Interlocked.Increment(ref connects); server.OnClientDisconnected += () => Interlocked.Increment(ref disconnects); var socket = new KafkaTcpSocket(new DefaultTraceLog(), _fakeServerUrl); var resultTask = ReadFromSocketWithRetry(socket, 4); //wait till connected TaskTest.WaitFor(() => connects > 0); //drop connection server.DropConnection(); TaskTest.WaitFor(() => disconnects > 0); Assert.That(disconnects, Is.EqualTo(1), "Server should have disconnected the client."); //wait for reconnection TaskTest.WaitFor(() => connects > 1); Assert.That(connects, Is.EqualTo(2), "Socket should have reconnected."); //send data and get result server.SendDataAsync(99.ToBytes()); Assert.That(resultTask.Result.ToInt32(), Is.EqualTo(99), "Socket should have received the 4 bytes."); } }
public void SendAsyncShouldTimeoutMultipleMessagesAtATime() { using (var server = new FakeTcpServer(8999)) using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint)) using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(100), log: _log)) { TaskTest.WaitFor(() => server.ConnectionEventcount > 0); Assert.That(server.ConnectionEventcount, Is.EqualTo(1)); var tasks = new[] { conn.SendAsync(new MetadataRequest()), conn.SendAsync(new MetadataRequest()), conn.SendAsync(new MetadataRequest()) }; Task.WhenAll(tasks); TaskTest.WaitFor(() => tasks.Any(t => t.IsFaulted)); foreach (var task in tasks) { Assert.That(task.IsFaulted, Is.True); Assert.That(task.Exception.InnerException, Is.TypeOf <ResponseTimeoutException>()); } } }
public void ReadShouldBlockUntilAllBytesRequestedAreReceived() { using (var server = new FakeTcpServer(FakeServerPort)) { var count = 0; var test = new KafkaTcpSocket(new DefaultTraceLog(), _fakeServerUrl); var resultTask = test.ReadAsync(4).ContinueWith(t => { Interlocked.Increment(ref count); return(t.Result); }); Console.WriteLine("Sending first 3 bytes..."); var sendInitialBytes = server.SendDataAsync(new byte[] { 0, 0, 0 }).Wait(TimeSpan.FromSeconds(10)); Assert.That(sendInitialBytes, Is.True, "First 3 bytes should have been sent."); Console.WriteLine("Ensuring task blocks..."); var unblocked = resultTask.Wait(TimeSpan.FromMilliseconds(500)); Assert.That(unblocked, Is.False, "Wait should return false."); Assert.That(resultTask.IsCompleted, Is.False, "Task should still be running, blocking."); Assert.That(count, Is.EqualTo(0), "Should still block even though bytes have been received."); Console.WriteLine("Sending last byte..."); var sendLastByte = server.SendDataAsync(new byte[] { 0 }).Wait(TimeSpan.FromSeconds(10)); Assert.That(sendLastByte, Is.True, "Last byte should have sent."); Console.WriteLine("Ensuring task unblocks..."); resultTask.Wait(TimeSpan.FromMilliseconds(500)); Assert.That(resultTask.IsCompleted, Is.True, "Task should have completed."); Assert.That(count, Is.EqualTo(1), "Task ContinueWith should have executed."); Assert.That(resultTask.Result.Length, Is.EqualTo(4), "Result of task should be 4 bytes."); } }
public void WriteShouldCancelWhileSendingData() { var writeAttempts = 0; using (var server = new FakeTcpServer(FakeServerPort)) using (var test = new KafkaTcpSocket(new DefaultTraceLog(), _fakeServerUrl)) using (var token = new CancellationTokenSource()) { test.OnWriteToSocketAttempt += payload => Interlocked.Increment(ref writeAttempts); test.WriteAsync(new KafkaDataPayload { Buffer = 1.ToBytes() }, token.Token); TaskTest.WaitFor(() => server.ConnectionEventcount > 0); TaskTest.WaitFor(() => writeAttempts > 0); Assert.That(writeAttempts, Is.EqualTo(1), "Socket should have attempted to write."); //create a buffer write that will take a long time var taskResult = test.WriteAsync( new KafkaDataPayload { Buffer = Enumerable.Range(0, 1000000).Select(b => (byte)b).ToArray() }, token.Token); token.Cancel(); taskResult.SafeWait(TimeSpan.FromMilliseconds(5000)); Assert.That(taskResult.IsCanceled, Is.True, "Task should have cancelled."); } }
public async Task KafkaConnectionShouldLogDisconnectAndRecover() { var mockLog = new Mock <IKafkaLog>(); var log = new DefaultTraceLog(LogLevel.Error); using (var server = new FakeTcpServer(log, 8999)) using (var socket = new KafkaTcpSocket(log, _kafkaEndpoint, _maxRetry)) using (var conn = new KafkaConnection(socket, log: mockLog.Object)) { var disconnected = 0; socket.OnServerDisconnected += () => Interlocked.Increment(ref disconnected); for (int connectionAttempt = 1; connectionAttempt < 4; connectionAttempt++) { await TaskTest.WaitFor(() => server.ConnectionEventcount == connectionAttempt); Assert.That(server.ConnectionEventcount, Is.EqualTo(connectionAttempt)); server.SendDataAsync(CreateCorrelationMessage(1)).Wait(TimeSpan.FromSeconds(5)); await TaskTest.WaitFor(() => !conn.IsOnErrorState()); Assert.IsFalse(conn.IsOnErrorState()); mockLog.Verify(x => x.InfoFormat("Polling read thread has recovered: {0}", It.IsAny <object[]>()), Times.Exactly(connectionAttempt - 1)); server.DropConnection(); await TaskTest.WaitFor(() => conn.IsOnErrorState()); Assert.AreEqual(disconnected, connectionAttempt); Assert.IsTrue(conn.IsOnErrorState()); mockLog.Verify(x => x.ErrorFormat("Exception occured in polling read thread {0}: {1}", It.IsAny <object[]>()), Times.Exactly(connectionAttempt)); } } }
public async Task SendAsyncShouldTimeoutMultipleMessagesAtATime() { using (var server = new FakeTcpServer(_log, 8999)) using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint, _maxRetry)) using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(100), log: _log)) { server.HasClientConnected.Wait(TimeSpan.FromSeconds(3)); Assert.That(server.ConnectionEventcount, Is.EqualTo(1)); var tasks = new[] { conn.SendAsync(new MetadataRequest()), conn.SendAsync(new MetadataRequest()), conn.SendAsync(new MetadataRequest()) }; Task.WhenAll(tasks); await TaskTest.WaitFor(() => tasks.All(t => t.IsFaulted)); foreach (var task in tasks) { Assert.That(task.IsFaulted, Is.True, "Task should have faulted."); Assert.That(task.Exception.InnerException, Is.TypeOf <ResponseTimeoutException>(), "Task fault should be of type ResponseTimeoutException."); } } }
public async Task ReadShouldIgnoreMessageWithUnknownCorrelationId() { const int correlationId = 99; var mockLog = _kernel.GetMock <IKafkaLog>(); using (var server = new FakeTcpServer(_log, 8999)) using (var socket = new KafkaTcpSocket(mockLog.Object, _kafkaEndpoint, _maxRetry)) using (var conn = new KafkaConnection(socket, log: mockLog.Object)) { var receivedData = false; socket.OnBytesReceived += i => receivedData = true; //send correlation message server.SendDataAsync(CreateCorrelationMessage(correlationId)).Wait(TimeSpan.FromSeconds(5)); //wait for connection await TaskTest.WaitFor(() => server.ConnectionEventcount > 0); Assert.That(server.ConnectionEventcount, Is.EqualTo(1)); await TaskTest.WaitFor(() => receivedData); //should log a warning and keep going mockLog.Verify(x => x.WarnFormat(It.IsAny <string>(), It.Is <int>(o => o == correlationId))); } }
public void KafkaTcpSocketShouldConstruct() { using (var test = new KafkaTcpSocket(new DefaultTraceLog(), _fakeServerUrl)) { Assert.That(test, Is.Not.Null); Assert.That(test.Endpoint, Is.EqualTo(_fakeServerUrl)); } }
public void KafkaTcpSocketShouldConstruct() { using (var test = new KafkaTcpSocket(_log, _fakeServerUrl, _maxRetry)) { Assert.That(test, Is.Not.Null); Assert.That(test.Endpoint, Is.EqualTo(_fakeServerUrl)); } }
public void ShouldStartReadPollingOnConstruction() { using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint)) using (var conn = new KafkaConnection(socket, log: _log)) { TaskTest.WaitFor(() => conn.ReadPolling); Assert.That(conn.ReadPolling, Is.True); } }
public void ShouldStartReadPollingOnConstruction() { using (var socket = new KafkaTcpSocket(_log, new Uri("http://localhost:8999"))) using (var conn = new KafkaConnection(socket, log: _log)) { TaskTest.WaitFor(() => conn.ReadPolling); Assert.That(conn.ReadPolling, Is.True); } }
public void ShouldReportServerUriOnConstruction() { var expectedUrl = new Uri("http://localhost:8999"); using (var socket = new KafkaTcpSocket(_log, expectedUrl)) using (var conn = new KafkaConnection(socket, log: _log)) { Assert.That(conn.KafkaUri, Is.EqualTo(expectedUrl)); } }
public async Task WhenNoConnectionThrowSocketException() { var socket = new KafkaTcpSocket(_log, new KafkaEndpoint() { ServeUri = new Uri("http://not.com") }, _maxRetry); var resultTask = socket.ReadAsync(4); await resultTask; }
public void ShouldDisposeWithoutExceptionEvenWhileCallingSendAsync() { using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint)) using (var conn = new KafkaConnection(socket, log: _log)) { var task = conn.SendAsync(new MetadataRequest()); task.Wait(TimeSpan.FromMilliseconds(1000)); Assert.That(task.IsCompleted, Is.False, "The send task should still be pending."); } }
public void ShouldReportServerUriOnConstruction() { var expectedUrl = _kafkaEndpoint; using (var socket = new KafkaTcpSocket(_log, expectedUrl)) using (var conn = new KafkaConnection(socket, log: _log)) { Assert.That(conn.Endpoint, Is.EqualTo(expectedUrl)); } }
public void ShouldDisposeWithoutExceptionThrown() { using (var server = new FakeTcpServer(8999)) using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint)) { var conn = new KafkaConnection(socket, log: _log); TaskTest.WaitFor(() => server.ConnectionEventcount > 0); using (conn) { } } }
public void ConnectionNotShouldAttemptOnConstruction() { var count = 0; using (var test = new KafkaTcpSocket(new DefaultTraceLog(), _fakeServerUrl)) { test.OnReconnectionAttempt += x => Interlocked.Increment(ref count); TaskTest.WaitFor(() => count > 0); Assert.That(count, Is.EqualTo(0)); } }
public void ConnectionShouldAttemptMultipleTimesWhenConnectionFails() { var count = 0; using (var test = new KafkaTcpSocket(new DefaultTraceLog(), _badServerUrl)) { test.WriteAsync(1.ToBytes()); //will force a connection test.OnReconnectionAttempt += x => Interlocked.Increment(ref count); TaskTest.WaitFor(() => count > 1, 10000); Assert.That(count, Is.GreaterThan(1)); } }
public async Task ConnectionShouldStartDedicatedThreadOnConstruction() { var count = 0; using (var test = new KafkaTcpSocket(_log, _fakeServerUrl, _maxRetry)) { test.OnReconnectionAttempt += x => Interlocked.Increment(ref count); await TaskTest.WaitFor(() => count > 0); Assert.That(count, Is.GreaterThan(0)); } }
public void KafkaTcpSocketShouldDisposeEvenWhilePollingToReconnect() { var test = new KafkaTcpSocket(new DefaultTraceLog(), _fakeServerUrl); var taskResult = test.ReadAsync(4); using (test) { } taskResult.ContinueWith(t => taskResult = t).Wait(TimeSpan.FromSeconds(1)); Assert.That(taskResult.IsFaulted, Is.True); Assert.That(taskResult.Exception.InnerException, Is.TypeOf <ObjectDisposedException>()); }
public async Task ConnectionShouldAttemptMultipleTimesWhenConnectionFails() { var count = 0; using (var test = new KafkaTcpSocket(_log, _badServerUrl, _maxRetry)) { test.WriteAsync(1.ToBytes().ToPayload()); //will force a connection test.OnReconnectionAttempt += x => Interlocked.Increment(ref count); await TaskTest.WaitFor(() => count > 1, 10000); Assert.That(count, Is.GreaterThan(1)); } }
public void SendAsyncShouldTimeoutByThrowingResponseTimeoutExceptionWhenTcpConnectionIsNotAvailable() { using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint)) using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(100), log: _log)) { var taskResult = conn.SendAsync(new MetadataRequest()); taskResult.ContinueWith(t => taskResult = t).Wait(TimeSpan.FromSeconds(1)); Assert.That(taskResult.IsFaulted, Is.True); Assert.That(taskResult.Exception.InnerException, Is.TypeOf <ResponseTimeoutException>()); } }
public void KafkaTcpSocketShouldDisposeEvenWhileWriting() { var test = new KafkaTcpSocket(new DefaultTraceLog(), _fakeServerUrl); var taskResult = test.WriteAsync(4.ToBytes()); using (test) { } //allow the sockets to set taskResult.ContinueWith(t => taskResult = t).Wait(TimeSpan.FromSeconds(20)); Assert.That(taskResult.IsCompleted, Is.True); Assert.That(taskResult.IsFaulted, Is.True, "Task should result indicate a fault."); Assert.That(taskResult.Exception.InnerException, Is.TypeOf <ObjectDisposedException>(), "Exception should be a disposed exception."); }
public async Task WhenNoConnectionThrowSocketExceptionAfterMaxRetry() { var reconnectionAttempt = 0; var socket = new KafkaTcpSocket(_log, new KafkaEndpoint() { ServeUri = new Uri("http://not.com") }, _maxRetry); socket.OnReconnectionAttempt += (x) => Interlocked.Increment(ref reconnectionAttempt); var resultTask = socket.ReadAsync(4); await resultTask; Assert.Equals(reconnectionAttempt, _maxRetry); }