public void BehaviorAfterCompleteCalled() { var fake = new FakeWriter(); var writer = new BufferedClientStreamWriter <string>(fake, 5); writer.WriteCompleteAsync(); // The (object) casts are because to make xUnit understand that the call itself should throw; // we don't return a failed task. Assert.Throws <InvalidOperationException>(() => (object)writer.WriteCompleteAsync()); Assert.Throws <InvalidOperationException>(() => (object)writer.WriteAsync("x")); Assert.Null(writer.TryWriteAsync("y")); }
public void WritesAfterMessagesAreSent() { // Unlike most other tests, here we write a message, the server completes the // task, write another message, server completes etc. var fake = new FakeWriter(); var writer = new BufferedClientStreamWriter <string>(fake, 5); // First message var task1 = writer.WriteAsync("1"); fake.CompleteCurrentTask(); AssertCompletedWithStatus(task1, TaskStatus.RanToCompletion); // Second message var task2 = writer.WriteAsync("2"); fake.CompleteCurrentTask(); AssertCompletedWithStatus(task2, TaskStatus.RanToCompletion); // Completion var completionTask = writer.WriteCompleteAsync(); fake.CompleteCurrentTask(); AssertCompletedWithStatus(completionTask, TaskStatus.RanToCompletion); fake.AssertMessages("1", "2"); fake.AssertCompleted(); }
public void CompleteAfterMessages() { var fake = new FakeWriter(); var writer = new BufferedClientStreamWriter <string>(fake, 5); var task1 = writer.WriteAsync("1"); var task2 = writer.WriteAsync("2"); var completionTask = writer.WriteCompleteAsync(); AssertNotCompleted(task1, task2, completionTask); // Server handles first message fake.CompleteCurrentTask(); AssertCompletedWithStatus(task1, TaskStatus.RanToCompletion); AssertNotCompleted(task2, completionTask); // Server handles second message fake.CompleteCurrentTask(); AssertCompletedWithStatus(task2, TaskStatus.RanToCompletion); AssertNotCompleted(completionTask); // Server handles completion fake.CompleteCurrentTask(); AssertCompletedWithStatus(completionTask, TaskStatus.RanToCompletion); fake.AssertMessages("1", "2"); fake.AssertCompleted(); }
public void FaultedWriteFailsPendingTasks() { var fake = new FakeWriter(); var writer = new BufferedClientStreamWriter <string>(fake, 5); var task1 = writer.WriteAsync("1"); var task2 = writer.WriteAsync("2"); var task3 = writer.WriteAsync("3"); var completionTask = writer.WriteCompleteAsync(); AssertNotCompleted(task1, task2, task3, completionTask); // Server handles first message successfully fake.CompleteCurrentTask(); AssertCompletedWithStatus(task1, TaskStatus.RanToCompletion); AssertNotCompleted(task2, task3, completionTask); // Server fails second message. All pending tasks become faulted with the same exception. var exception = new Exception("Bang"); fake.FailCurrentTask(exception); foreach (var task in new[] { task2, task3, completionTask }) { AssertCompletedWithStatus(task, TaskStatus.Faulted); Assert.Same(exception, task.Exception.InnerExceptions[0]); } }
public void CompleteWithNoWrites() { var fake = new FakeWriter(); var writer = new BufferedClientStreamWriter <string>(fake, 5); var completionTask = writer.WriteCompleteAsync(); fake.CompleteCurrentTask(); AssertCompletedWithStatus(completionTask, TaskStatus.RanToCompletion); fake.AssertMessages(); fake.AssertCompleted(); }
public void CompletionUsesBufferSpace() { var fake = new FakeWriter(); var writer = new BufferedClientStreamWriter <string>(fake, 2); writer.WriteAsync("1"); writer.WriteAsync("2"); // Try completion, should throw because queue is full. // The (object) cast is because to make xUnit understand that the call itself should throw; // we don't return a failed task. Assert.Throws <InvalidOperationException>(() => (object)writer.WriteCompleteAsync()); // Try completion, should return null because queue is full. Assert.Null(writer.TryWriteCompleteAsync()); fake.CompleteCurrentTask(); fake.CompleteCurrentTask(); writer.WriteCompleteAsync(); fake.CompleteCurrentTask(); fake.AssertCompleted(); }
public void WriteBeyondBuffer() { var fake = new FakeWriter(); var writer = new BufferedClientStreamWriter <string>(fake, 2); var task1 = writer.WriteAsync("1"); var task2 = writer.WriteAsync("2"); // The (object) cast is because to make xUnit understand that the call itself should throw; // we don't return a failed task. Assert.Throws <InvalidOperationException>(() => (object)writer.WriteAsync("3")); fake.CompleteCurrentTask(); // Message 1 WaitForSpace(writer); // Now the buffer is smaller, we can write again. var task4 = writer.WriteAsync("4"); // Completion fails, no space in buffer Assert.Throws <InvalidOperationException>(() => (object)writer.WriteCompleteAsync()); fake.CompleteCurrentTask(); // Message 2 WaitForSpace(writer); // Completion succeeds, there is now space in the buffer. var completionTask = writer.WriteCompleteAsync(); fake.CompleteCurrentTask(); // Message 4 fake.CompleteCurrentTask(); // Completion AssertCompletedWithStatus(task1, TaskStatus.RanToCompletion); AssertCompletedWithStatus(task2, TaskStatus.RanToCompletion); AssertCompletedWithStatus(task4, TaskStatus.RanToCompletion); AssertCompletedWithStatus(completionTask, TaskStatus.RanToCompletion); fake.AssertMessages("1", "2", "4"); fake.AssertCompleted(); }
public void FaultedWriteFailsFutureTasks() { var fake = new FakeWriter(); var writer = new BufferedClientStreamWriter <string>(fake, 5); var task1 = writer.WriteAsync("1"); // Server fails first message var exception = new Exception("Bang"); fake.FailCurrentTask(exception); // Subsequent calls to Write and Complete fail var task2 = writer.WriteAsync("2"); var task3 = writer.WriteAsync("3"); var completionTask = writer.WriteCompleteAsync(); foreach (var task in new[] { task1, task2, task3, completionTask }) { AssertCompletedWithStatus(task, TaskStatus.Faulted); Assert.Same(exception, task.Exception.InnerExceptions[0]); } }
/// <inheritdoc/> public override Task WriteCompleteAsync() => _writeBuffer.WriteCompleteAsync();