Fixing logger nullref when context created with no feature #532

This commit is contained in:
John Luo 2016-01-11 16:57:59 -08:00
parent fa72fdeaed
commit f7be1fb80e
5 changed files with 90 additions and 19 deletions

View File

@ -124,12 +124,13 @@ namespace Microsoft.AspNet.TestHost
request.Headers.Host = request.RequestUri.GetComponents(UriComponents.HostAndPort, UriFormat.UriEscaped);
}
Context = application.CreateContext(new FeatureCollection());
var contextFeatures = new FeatureCollection();
contextFeatures.Set<IHttpRequestFeature>(new RequestFeature());
_responseFeature = new ResponseFeature();
contextFeatures.Set<IHttpResponseFeature>(_responseFeature);
Context = application.CreateContext(contextFeatures);
var httpContext = Context.HttpContext;
httpContext.Features.Set<IHttpRequestFeature>(new RequestFeature());
_responseFeature = new ResponseFeature();
httpContext.Features.Set<IHttpResponseFeature>(_responseFeature);
var serverRequest = httpContext.Request;
serverRequest.Protocol = "HTTP/" + request.Version.ToString(2);
serverRequest.Scheme = request.RequestUri.Scheme;

View File

@ -98,11 +98,13 @@ namespace Microsoft.AspNet.TestHost
_application = application;
// HttpContext
Context = _application.CreateContext(new FeatureCollection());
var contextFeatures = new FeatureCollection();
contextFeatures.Set<IHttpRequestFeature>(new RequestFeature());
contextFeatures.Set<IHttpResponseFeature>(new ResponseFeature());
Context = _application.CreateContext(contextFeatures);
var httpContext = Context.HttpContext;
// Request
httpContext.Features.Set<IHttpRequestFeature>(new RequestFeature());
var request = httpContext.Request;
request.Protocol = "HTTP/1.1";
var scheme = uri.Scheme;
@ -130,7 +132,6 @@ namespace Microsoft.AspNet.TestHost
request.Body = Stream.Null;
// Response
httpContext.Features.Set<IHttpResponseFeature>(new ResponseFeature());
var response = httpContext.Response;
response.Body = Stream.Null;
response.StatusCode = 200;

View File

@ -5,13 +5,19 @@ using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Hosting.Internal;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Testing.xunit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Xunit;
using Context = Microsoft.AspNet.Hosting.Internal.HostingApplication.Context;
@ -269,5 +275,47 @@ namespace Microsoft.AspNet.TestHost
return _application(context.HttpContext);
}
}
[ConditionalFact]
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task ClientHandlerCreateContextWithDefaultRequestParameters()
{
// This logger will attempt to access information from HttpRequest once the HttpContext is created
var logger = new VerifierLogger();
var builder = new WebApplicationBuilder()
.ConfigureServices(services =>
{
services.AddSingleton<ILogger<WebApplication>>(logger);
})
.Configure(app =>
{
app.Run(context =>
{
return Task.FromResult(0);
});
});
var server = new TestServer(builder);
// The HttpContext will be created and the logger will make sure that the HttpRequest exists and contains reasonable values
var result = await server.CreateClient().GetStringAsync("/");
}
private class VerifierLogger : ILogger<WebApplication>
{
public IDisposable BeginScopeImpl(object state) => new NoopDispoasble();
public bool IsEnabled(LogLevel logLevel) => true;
// This call verifies that fields of HttpRequest are accessed and valid
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter) => formatter(state, exception);
class NoopDispoasble : IDisposable
{
public void Dispose()
{
}
}
}
}
}

View File

@ -11,21 +11,17 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Hosting.Internal;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Testing.xunit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Microsoft.AspNet.TestHost
{
public class TestClientTests
{
private readonly TestServer _server;
public TestClientTests()
{
_server = new TestServer(new WebApplicationBuilder().Configure(app => app.Run(ctx => Task.FromResult(0))));
}
[ConditionalFact]
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task GetAsyncWorks()
@ -134,6 +130,8 @@ namespace Microsoft.AspNet.TestHost
public async Task WebSocketWorks()
{
// Arrange
// This logger will attempt to access information from HttpRequest once the HttpContext is createds
var logger = new VerifierLogger();
RequestDelegate appDelegate = async ctx =>
{
if (ctx.WebSockets.IsWebSocketRequest)
@ -156,14 +154,20 @@ namespace Microsoft.AspNet.TestHost
}
}
};
var builder = new WebApplicationBuilder().Configure(app =>
{
app.Run(appDelegate);
});
var builder = new WebApplicationBuilder()
.ConfigureServices(services =>
{
services.AddSingleton<ILogger<WebApplication>>(logger);
})
.Configure(app =>
{
app.Run(appDelegate);
});
var server = new TestServer(builder);
// Act
var client = server.CreateWebSocketClient();
// The HttpContext will be created and the logger will make sure that the HttpRequest exists and contains reasonable values
var clientSocket = await client.ConnectAsync(new System.Uri("http://localhost"), CancellationToken.None);
var hello = Encoding.UTF8.GetBytes("hello");
await clientSocket.SendAsync(new System.ArraySegment<byte>(hello), WebSocketMessageType.Text, true, CancellationToken.None);
@ -192,6 +196,24 @@ namespace Microsoft.AspNet.TestHost
clientSocket.Dispose();
}
private class VerifierLogger : ILogger<WebApplication>
{
public IDisposable BeginScopeImpl(object state) => new NoopDispoasble();
public bool IsEnabled(LogLevel logLevel) => true;
// This call verifies that fields of HttpRequest are accessed and valid
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter) => formatter(state, exception);
class NoopDispoasble : IDisposable
{
public void Dispose()
{
}
}
}
[ConditionalFact]
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Hangs randomly (issue #507)")]
public async Task WebSocketDisposalThrowsOnPeer()

View File

@ -10,7 +10,6 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http.Features.Internal;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Testing.xunit;