Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 769cfb8

Browse files
committed
WIP 11
1 parent 0760f29 commit 769cfb8

28 files changed

+678
-733
lines changed

src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/ConnectionHandler.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,16 @@ public void Dispose()
7575
_pipeFactory.Dispose();
7676
}
7777

78-
private PipeOptions GetInputPipeOptions(IScheduler scheduler) => new PipeOptions
78+
// Internal for testing
79+
internal PipeOptions GetInputPipeOptions(IScheduler scheduler) => new PipeOptions
7980
{
8081
ReaderScheduler = _serviceContext.ThreadPool,
8182
WriterScheduler = scheduler,
8283
MaximumSizeHigh = _serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
8384
MaximumSizeLow = _serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0
8485
};
8586

86-
private PipeOptions GetOutputPipeOptions(IScheduler scheduler) => new PipeOptions
87+
internal PipeOptions GetOutputPipeOptions(IScheduler scheduler) => new PipeOptions
8788
{
8889
ReaderScheduler = scheduler,
8990
WriterScheduler = _serviceContext.ThreadPool,

src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/ConnectionLifetime.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ public ConnectionLifetime(ConnectionLifetimeContext context)
3939
public IPipeReader Output => _context.Output.Reader;
4040

4141
private PipeFactory PipeFactory => _context.PipeFactory;
42-
private PipeOptions AdaptedPipeOptions => new PipeOptions
42+
43+
// Internal for testing
44+
internal PipeOptions AdaptedPipeOptions => new PipeOptions
4345
{
4446
ReaderScheduler = InlineScheduler.Default,
4547
WriterScheduler = InlineScheduler.Default,

src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ public Task StopAsync()
408408
return _requestProcessingTask ?? TaskCache.CompletedTask;
409409
}
410410

411-
public void CancelRequestAbortedToken()
411+
private void CancelRequestAbortedToken()
412412
{
413413
try
414414
{

src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/SocketOutputProducer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
1212
{
13-
public class SocketOutputProducer : ISocketOutput
13+
public class SocketOutputProducer : ISocketOutput, IDisposable
1414
{
1515
private static readonly ArraySegment<byte> _emptyData = new ArraySegment<byte>(new byte[0]);
1616

src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -212,23 +212,25 @@ public void Start<TContext>(IHttpApplication<TContext> application)
212212

213213
public void Dispose()
214214
{
215-
var tasks = new Task[_transports.Count];
216-
for (int i = 0; i < _transports.Count; i++)
215+
if (_transports != null)
217216
{
218-
tasks[i] = _transports[i].UnbindAsync();
219-
}
220-
Task.WaitAll(tasks);
221-
222-
_connectionHandlerDisposable.Dispose();
217+
var tasks = new Task[_transports.Count];
218+
for (int i = 0; i < _transports.Count; i++)
219+
{
220+
tasks[i] = _transports[i].UnbindAsync();
221+
}
222+
Task.WaitAll(tasks);
223223

224-
// TODO: Do transport-agnostic connection management/shutdown.
225-
for (int i = 0; i < _transports.Count; i++)
226-
{
227-
tasks[i] = _transports[i].StopAsync();
224+
// TODO: Do transport-agnostic connection management/shutdown.
225+
for (int i = 0; i < _transports.Count; i++)
226+
{
227+
tasks[i] = _transports[i].StopAsync();
228+
}
229+
Task.WaitAll(tasks);
228230
}
229-
Task.WaitAll(tasks);
230231

231-
_dateHeaderValueManager.Dispose();
232+
_connectionHandlerDisposable?.Dispose();
233+
_dateHeaderValueManager?.Dispose();
232234
}
233235

234236
private void ValidateOptions()

src/Microsoft.AspNetCore.Server.Kestrel.Libuv/Internal/Http/SocketOutputConsumer.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,5 @@ private Task ShutdownAsync()
139139

140140
return tcs.Task;
141141
}
142-
143-
public void Shutdown()
144-
{
145-
// Graceful shutdown.
146-
_pipe.CancelPendingRead();
147-
}
148142
}
149143
}

src/Microsoft.AspNetCore.Server.Kestrel.Libuv/Internal/Infrastructure/KestrelThread.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ public KestrelThread(KestrelEngine engine)
7878
WriteReqPool = new WriteReqPool(this, _log);
7979
ConnectionManager = new ConnectionManager(this);
8080
}
81+
8182
// For testing
82-
internal KestrelThread(KestrelEngine engine, int maxLoops)
83+
public KestrelThread(KestrelEngine engine, int maxLoops)
8384
: this(engine)
8485
{
8586
_maxLoops = maxLoops;

src/Microsoft.AspNetCore.Server.Kestrel.Libuv/LibuvTransportFactory.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public LibuvTransportFactory(
3939
// TODO: Add LibuvTrace
4040
var trace = new KestrelTrace(logger);
4141

42-
4342
var threadCount = options.Value.ThreadCount;
4443

4544
if (threadCount <= 0)

test/Microsoft.AspNetCore.Server.KestrelTests/ConnectionTests.cs

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@ public class ConnectionTests
2323
[Fact]
2424
public async Task DoesNotEndConnectionOnZeroRead()
2525
{
26-
27-
using (var testConnectionHandler = new TestConnectionHandler())
26+
using (var mockConnectionHandler = new MockConnectionHandler())
2827
{
2928
var mockLibuv = new MockLibuv();
3029
var serviceContext = new TestServiceContext();
31-
serviceContext.TransportContext.ConnectionHandler = testConnectionHandler;
30+
serviceContext.TransportContext.ConnectionHandler = mockConnectionHandler;
3231

3332
var engine = new KestrelEngine(mockLibuv, serviceContext.TransportContext, null);
3433
var thread = new KestrelThread(engine);
@@ -51,7 +50,7 @@ await thread.PostAsync(_ =>
5150
mockLibuv.ReadCallback(socket.InternalGetHandle(), 0, ref ignored);
5251
}, (object)null);
5352

54-
var readAwaitable = await testConnectionHandler.Input.Reader.ReadAsync();
53+
var readAwaitable = await mockConnectionHandler.Input.Reader.ReadAsync();
5554
Assert.False(readAwaitable.IsCompleted);
5655
}
5756
finally
@@ -60,57 +59,5 @@ await thread.PostAsync(_ =>
6059
}
6160
}
6261
}
63-
64-
private class TestConnectionHandler : IConnectionHandler, IDisposable
65-
{
66-
private readonly PipeFactory _pipeFactory;
67-
68-
public IPipe Input;
69-
70-
public TestConnectionHandler()
71-
{
72-
_pipeFactory = new PipeFactory();
73-
}
74-
75-
public IConnectionContext OnConnection(IConnectionInformation connectionInfo, IScheduler inputWriterScheduler, IScheduler outputReaderScheduler)
76-
{
77-
Assert.Null(Input);
78-
79-
Input = _pipeFactory.Create();
80-
81-
return new TestConnectionContext
82-
{
83-
Input = Input.Writer,
84-
};
85-
}
86-
87-
public void Dispose()
88-
{
89-
Input?.Writer.Complete();
90-
_pipeFactory.Dispose();
91-
}
92-
93-
private class TestConnectionContext : IConnectionContext
94-
{
95-
public string ConnectionId { get; }
96-
public IPipeWriter Input { get; set; }
97-
public IPipeReader Output { get; set; }
98-
99-
public Task StopAsync()
100-
{
101-
throw new NotImplementedException();
102-
}
103-
104-
public void Abort(Exception ex)
105-
{
106-
throw new NotImplementedException();
107-
}
108-
109-
public void SetBadRequestState(RequestRejectionReason reason)
110-
{
111-
throw new NotImplementedException();
112-
}
113-
}
114-
}
11562
}
11663
}

test/Microsoft.AspNetCore.Server.KestrelTests/EngineTests.cs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
using Microsoft.AspNetCore.Server.Kestrel;
1616
using Microsoft.AspNetCore.Server.Kestrel.Internal;
1717
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
18-
using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking;
19-
using Microsoft.AspNetCore.Server.KestrelTests.TestHelpers;
2018
using Microsoft.AspNetCore.Testing;
2119
using Microsoft.Extensions.Internal;
2220
using Xunit;
@@ -38,35 +36,40 @@ public class EngineTests
3836
};
3937

4038
[Fact]
41-
public void EngineCanStartAndStop()
39+
public async Task EngineCanStartAndStop()
4240
{
43-
var engine = new KestrelEngine(new TestServiceContext());
44-
engine.Start(1);
45-
engine.Dispose();
41+
var serviceContext = new TestServiceContext();
42+
43+
// The engine can no longer start threads without binding to an endpoint.
44+
var engine = new KestrelEngine(serviceContext.TransportContext,
45+
new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)));
46+
47+
await engine.BindAsync();
48+
await engine.StopAsync();
4649
}
4750

4851
[Theory]
4952
[MemberData(nameof(ConnectionAdapterData))]
50-
public void ListenerCanCreateAndDispose(ListenOptions listenOptions)
53+
public async Task ListenerCanCreateAndDispose(ListenOptions listenOptions)
5154
{
5255
var testContext = new TestServiceContext();
5356
testContext.App = TestApp.EchoApp;
54-
var engine = new KestrelEngine(testContext);
55-
engine.Start(1);
56-
var started = engine.CreateServer(listenOptions);
57-
started.Dispose();
58-
engine.Dispose();
57+
var engine = new KestrelEngine(testContext.TransportContext, listenOptions);
58+
59+
await engine.BindAsync();
60+
await engine.UnbindAsync();
61+
await engine.StopAsync();
5962
}
6063

6164
[Theory]
6265
[MemberData(nameof(ConnectionAdapterData))]
63-
public void ConnectionCanReadAndWrite(ListenOptions listenOptions)
66+
public async Task ConnectionCanReadAndWrite(ListenOptions listenOptions)
6467
{
6568
var testContext = new TestServiceContext();
6669
testContext.App = TestApp.EchoApp;
67-
var engine = new KestrelEngine(testContext);
68-
engine.Start(1);
69-
var started = engine.CreateServer(listenOptions);
70+
var engine = new KestrelEngine(testContext.TransportContext, listenOptions);
71+
72+
await engine.BindAsync();
7073

7174
var socket = TestConnection.CreateConnectedLoopbackSocket(listenOptions.IPEndPoint.Port);
7275
var data = "Hello World";
@@ -78,8 +81,9 @@ public void ConnectionCanReadAndWrite(ListenOptions listenOptions)
7881
read += socket.Receive(buffer, read, buffer.Length - read, SocketFlags.None);
7982
}
8083
socket.Dispose();
81-
started.Dispose();
82-
engine.Dispose();
84+
85+
await engine.UnbindAsync();
86+
await engine.StopAsync();
8387
}
8488

8589
[Theory]
@@ -798,7 +802,7 @@ await connection.ReceiveForcedEnd(
798802
Assert.True(onStartingCalled);
799803
Assert.Equal(1, testLogger.ApplicationErrorsLogged);
800804
}
801-
805+
802806
[MemberData(nameof(ConnectionAdapterData))]
803807
public async Task ConnectionClosesWhenFinReceivedBeforeRequestCompletes(ListenOptions listenOptions)
804808
{

test/Microsoft.AspNetCore.Server.KestrelTests/FrameResponseHeadersTests.cs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Microsoft.AspNetCore.Server.Kestrel;
1111
using Microsoft.AspNetCore.Server.Kestrel.Internal;
1212
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
13+
using Microsoft.AspNetCore.Testing;
1314
using Microsoft.Extensions.Primitives;
1415
using Xunit;
1516

@@ -20,21 +21,12 @@ public class FrameResponseHeadersTests
2021
[Fact]
2122
public void InitialDictionaryIsEmpty()
2223
{
23-
var serverOptions = new KestrelServerOptions();
24-
25-
var serviceContext = new ServiceContext
26-
{
27-
DateHeaderValueManager = new DateHeaderValueManager(),
28-
ServerOptions = serverOptions,
29-
HttpParserFactory = f => new NoopHttpParser(),
30-
};
31-
var listenerContext = new ListenerContext(serviceContext)
24+
var frameContext = new FrameContext
3225
{
33-
ListenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 5000))
26+
ServiceContext = new TestServiceContext()
3427
};
35-
var connectionContext = new ConnectionContext(listenerContext);
3628

37-
var frame = new Frame<object>(application: null, context: connectionContext);
29+
var frame = new Frame<object>(application: null, frameContext: frameContext);
3830

3931
frame.InitializeHeaders();
4032

@@ -287,7 +279,7 @@ public bool ParseRequestLine<T>(T handler, ReadableBuffer buffer, out ReadCursor
287279

288280
public void Reset()
289281
{
290-
282+
291283
}
292284
}
293285
}

0 commit comments

Comments
 (0)