-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Implement response BodyWriter, CompleteAsync for TestServer #11598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
May I ask why it is hard to test, does gRPC not work with the TestServer? I'm asking for my HttpBatchHandler middleware, which is very similar to the TestServer from ASP.NET Core 2.x, it still works in 3.0 (atleast the current tests do), but I'm not sure if I want to add the Pipe complexity to my middleware, so it would be nice to know which features might rely on new RequestFeature/ResponseFeature functionality (like that IHttpResponseCompletionFeature.CompleteAsync thing). |
I've just changed gRPC integration tests to use Kestrel instead of test server. HTTP/2 support in HttpClient is rather hot and I wanted more testing with it and gRPC. These TestServer improves are Good, but they don't need to be a priority because of gRPC. |
FYI running too many network tests can cause things like socket exhaustion, especially on Mac. Yes we need integration tests with HttpClient, but most unit tests should use TestServer or similar mocks. |
Note to self, Abort was only half implemented. It would fire RequestAborted, but not surface any errors to the client. |
@Tratcher is this happening as part of your big Response Body Feature thing? |
Only sortof. All servers (including TestServer) will now have a standard set of APIs (Stream, PipeWriter, StartAsync, CompleteAsync, SendFileAsync), but for this first pass we're polyfilling the implementations. We'll keep this item open fully implement CompleteAsync. |
Ok, I'll backlog it given that then. |
Is CompleteAsync still missing in .NET 5? I am seeing integration tests fail that worked before, because the exception seems to bubble out of an exception middleware that were supposed to intercept and handle it. |
@kparkov Yes, CompleteAsync is still a known gap. However, exception handlers should be based on the response starting, not ending. Are you using the built-in exception handler or something else? |
I have a custom built exception handler that is added to the end of the middleware chain. Like this: public static class GlobalExceptionHandler
{
public static void ConfigureGlobalExceptionHandler(this IApplicationBuilder app)
{
app.UseExceptionHandler(configure =>
{
configure.Use((context, next) =>
{
var exception = context.Features.Get<IExceptionHandlerFeature>()?.Error;
if (exception is null)
{
return next();
}
else
{
Feedback result;
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
if (exception is ClientException ce)
{
result = Feedback.Create(code: ce.InternalStatusCode, message: ce.Message, handled: true);
httpStatusCode = ce.HttpStatusCode;
}
else
{
#if DEBUG
result = Feedback.Create(code: InternalStatusCode.UnhandledServerException, message: exception.Message, handled: false, details: new ExceptionDetails(exception), trace: exception.StackTrace);
#else
result = Feedback.Create(code: InternalStatusCode.UnhandledServerException, message: $"An unknown exception of type {exception.GetType().Name} occured.", handled: false);
#endif
}
var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
var json = JsonConvert.SerializeObject(result, Formatting.Indented, settings);
context.Response.StatusCode = (int) httpStatusCode;
return context.Response.WriteAsync(json);
}
});
});
}
} However, the test server throws an EDIT: I considered modifying it using |
That looks fine. UseExceptionHandler shouldn't re-throw exceptions after you've called Response.WriteAsync. However, it will log and rethrow the original exception if your exception handler throws. Have you checked the logs and/or stepped through your exception handler in the debugger? |
Uh oh!
There was an error while loading. Please reload this page.
gRPC depends on pipes and a few other features only implemented by Kestrel such as StartAsync and CompleteAsync. Missing those features in TestServer makes it hard to test gRPC and related components.
TestServer already uses a pipe internally for its response data, but exposing it turns out to be complicated because we add lots of semantics on top such as the first flush sending headers, content-length verification, etc..
#11305
#11194
@JamesNK
The text was updated successfully, but these errors were encountered: