Clean up ManualResetEvent usage in tests (#6961)
This commit is contained in:
parent
65ee89a71e
commit
7d4b6fccff
|
|
@ -77,18 +77,16 @@ Global
|
|||
{766C394B-ABBB-4624-A071-C806C0A2CD3E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{766C394B-ABBB-4624-A071-C806C0A2CD3E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{766C394B-ABBB-4624-A071-C806C0A2CD3E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|x64.Build.0 = Debug|x64
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Debug|x86.Build.0 = Debug|x86
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|x64.ActiveCfg = Release|x64
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|x64.Build.0 = Release|x64
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|x86.ActiveCfg = Release|x86
|
||||
{BE8D7353-692B-4B5B-ADFD-32632AE758E3}.Release|x86.Build.0 = Release|x86
|
||||
{AE1F0124-996E-476A-9331-FB789F3D0577}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AE1F0124-996E-476A-9331-FB789F3D0577}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AE1F0124-996E-476A-9331-FB789F3D0577}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics.Tracing;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.HostFiltering;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -28,7 +30,7 @@ namespace Microsoft.AspNetCore.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void WebHostConfiguration_HostFilterOptionsAreReloadable()
|
||||
public async Task WebHostConfiguration_HostFilterOptionsAreReloadable()
|
||||
{
|
||||
var host = WebHost.CreateDefaultBuilder()
|
||||
.Configure(app => { })
|
||||
|
|
@ -42,15 +44,15 @@ namespace Microsoft.AspNetCore.Tests
|
|||
|
||||
Assert.Contains("*", options.AllowedHosts);
|
||||
|
||||
var changed = new ManualResetEvent(false);
|
||||
var changed = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
monitor.OnChange(newOptions =>
|
||||
{
|
||||
changed.Set();
|
||||
changed.SetResult(0);
|
||||
});
|
||||
|
||||
config["AllowedHosts"] = "NewHost";
|
||||
|
||||
Assert.True(changed.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
await changed.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
options = monitor.CurrentValue;
|
||||
Assert.Contains("NewHost", options.AllowedHosts);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Hosting;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
|
|
@ -460,7 +461,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
[MemberData(nameof(SupportedEncodingsWithBodyLength))]
|
||||
public async Task FlushHeaders_SendsHeaders_Compresses(string encoding, int expectedBodyLength)
|
||||
{
|
||||
var responseReceived = new ManualResetEvent(false);
|
||||
var responseReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
|
|
@ -470,13 +471,13 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
.Configure(app =>
|
||||
{
|
||||
app.UseResponseCompression();
|
||||
app.Run(context =>
|
||||
app.Run(async context =>
|
||||
{
|
||||
context.Response.Headers[HeaderNames.ContentMD5] = "MD5";
|
||||
context.Response.ContentType = TextPlain;
|
||||
context.Response.Body.Flush();
|
||||
Assert.True(responseReceived.WaitOne(TimeSpan.FromSeconds(3)));
|
||||
return context.Response.WriteAsync(new string('a', 100));
|
||||
await responseReceived.Task.TimeoutAfter(TimeSpan.FromSeconds(3));
|
||||
await context.Response.WriteAsync(new string('a', 100));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -487,7 +488,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
request.Headers.AcceptEncoding.ParseAdd(encoding);
|
||||
|
||||
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
responseReceived.Set();
|
||||
responseReceived.SetResult(0);
|
||||
|
||||
await response.Content.LoadIntoBufferAsync();
|
||||
|
||||
|
|
@ -498,7 +499,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
[MemberData(nameof(SupportedEncodingsWithBodyLength))]
|
||||
public async Task FlushAsyncHeaders_SendsHeaders_Compresses(string encoding, int expectedBodyLength)
|
||||
{
|
||||
var responseReceived = new ManualResetEvent(false);
|
||||
var responseReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
|
|
@ -513,7 +514,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
context.Response.Headers[HeaderNames.ContentMD5] = "MD5";
|
||||
context.Response.ContentType = TextPlain;
|
||||
await context.Response.Body.FlushAsync();
|
||||
Assert.True(responseReceived.WaitOne(TimeSpan.FromSeconds(3)));
|
||||
await responseReceived.Task.TimeoutAfter(TimeSpan.FromSeconds(3));
|
||||
await context.Response.WriteAsync(new string('a', 100));
|
||||
});
|
||||
});
|
||||
|
|
@ -525,7 +526,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
request.Headers.AcceptEncoding.ParseAdd(encoding);
|
||||
|
||||
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
responseReceived.Set();
|
||||
responseReceived.SetResult(0);
|
||||
|
||||
await response.Content.LoadIntoBufferAsync();
|
||||
|
||||
|
|
@ -536,7 +537,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
[MemberData(nameof(SupportedEncodings))]
|
||||
public async Task FlushBody_CompressesAndFlushes(string encoding)
|
||||
{
|
||||
var responseReceived = new ManualResetEvent(false);
|
||||
var responseReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
|
|
@ -546,7 +547,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
.Configure(app =>
|
||||
{
|
||||
app.UseResponseCompression();
|
||||
app.Run(context =>
|
||||
app.Run(async context =>
|
||||
{
|
||||
var feature = context.Features.Get<IHttpBodyControlFeature>();
|
||||
if (feature != null)
|
||||
|
|
@ -558,9 +559,8 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
context.Response.ContentType = TextPlain;
|
||||
context.Response.Body.Write(new byte[10], 0, 10);
|
||||
context.Response.Body.Flush();
|
||||
Assert.True(responseReceived.WaitOne(TimeSpan.FromSeconds(3)));
|
||||
await responseReceived.Task.TimeoutAfter(TimeSpan.FromSeconds(3));
|
||||
context.Response.Body.Write(new byte[90], 0, 90);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -579,7 +579,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
var read = await body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.True(read > 0);
|
||||
|
||||
responseReceived.Set();
|
||||
responseReceived.SetResult(0);
|
||||
|
||||
read = await body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.True(read > 0);
|
||||
|
|
@ -589,7 +589,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
[MemberData(nameof(SupportedEncodings))]
|
||||
public async Task FlushAsyncBody_CompressesAndFlushes(string encoding)
|
||||
{
|
||||
var responseReceived = new ManualResetEvent(false);
|
||||
var responseReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
|
|
@ -605,7 +605,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
context.Response.ContentType = TextPlain;
|
||||
await context.Response.WriteAsync(new string('a', 10));
|
||||
await context.Response.Body.FlushAsync();
|
||||
Assert.True(responseReceived.WaitOne(TimeSpan.FromSeconds(3)));
|
||||
await responseReceived.Task.TimeoutAfter(TimeSpan.FromSeconds(3));
|
||||
await context.Response.WriteAsync(new string('a', 90));
|
||||
});
|
||||
});
|
||||
|
|
@ -625,7 +625,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
var read = await body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.True(read > 0);
|
||||
|
||||
responseReceived.Set();
|
||||
responseReceived.SetResult(0);
|
||||
|
||||
read = await body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.True(read > 0);
|
||||
|
|
@ -637,11 +637,11 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
{
|
||||
var responseReceived = new[]
|
||||
{
|
||||
new ManualResetEvent(false),
|
||||
new ManualResetEvent(false),
|
||||
new ManualResetEvent(false),
|
||||
new ManualResetEvent(false),
|
||||
new ManualResetEvent(false),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
};
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
|
|
@ -652,7 +652,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
.Configure(app =>
|
||||
{
|
||||
app.UseResponseCompression();
|
||||
app.Run(context =>
|
||||
app.Run(async context =>
|
||||
{
|
||||
context.Response.Headers[HeaderNames.ContentMD5] = "MD5";
|
||||
context.Response.ContentType = TextPlain;
|
||||
|
|
@ -668,9 +668,8 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
{
|
||||
context.Response.Body.Write(new byte[1], 0, 1);
|
||||
context.Response.Body.Flush();
|
||||
Assert.True(signal.WaitOne(TimeSpan.FromSeconds(3)));
|
||||
await signal.Task.TimeoutAfter(TimeSpan.FromSeconds(3));
|
||||
}
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -691,7 +690,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
var read = await body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.True(read > 0);
|
||||
|
||||
signal.Set();
|
||||
signal.SetResult(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -701,11 +700,11 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
{
|
||||
var responseReceived = new[]
|
||||
{
|
||||
new ManualResetEvent(false),
|
||||
new ManualResetEvent(false),
|
||||
new ManualResetEvent(false),
|
||||
new ManualResetEvent(false),
|
||||
new ManualResetEvent(false),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously),
|
||||
};
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
|
|
@ -726,7 +725,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
{
|
||||
await context.Response.WriteAsync("a");
|
||||
await context.Response.Body.FlushAsync();
|
||||
Assert.True(signal.WaitOne(TimeSpan.FromSeconds(3)));
|
||||
await signal.Task.TimeoutAfter(TimeSpan.FromSeconds(3));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -748,7 +747,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
var read = await body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.True(read > 0);
|
||||
|
||||
signal.Set();
|
||||
signal.SetResult(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -918,7 +917,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
[MemberData(nameof(SupportedEncodings))]
|
||||
public async Task Dispose_SyncWriteOrFlushNotCalled(string encoding)
|
||||
{
|
||||
var responseReceived = new ManualResetEvent(false);
|
||||
var responseReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
|
|
@ -939,7 +938,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
context.Response.ContentType = TextPlain;
|
||||
await context.Response.WriteAsync(new string('a', 10));
|
||||
await context.Response.Body.FlushAsync();
|
||||
Assert.True(responseReceived.WaitOne(TimeSpan.FromSeconds(3)));
|
||||
await responseReceived.Task.TimeoutAfter(TimeSpan.FromSeconds(3));
|
||||
await context.Response.WriteAsync(new string('a', 90));
|
||||
});
|
||||
});
|
||||
|
|
@ -959,7 +958,7 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
var read = await body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.True(read > 0);
|
||||
|
||||
responseReceived.Set();
|
||||
responseReceived.SetResult(0);
|
||||
|
||||
read = await body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.True(read > 0);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Hosting;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
|
|
@ -164,25 +165,25 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
};
|
||||
|
||||
[Fact]
|
||||
public void ClientDisconnect_Kestrel_NoWriteExceptionThrown()
|
||||
public Task ClientDisconnect_Kestrel_NoWriteExceptionThrown()
|
||||
{
|
||||
ClientDisconnect_NoWriteExceptionThrown(ServerType.Kestrel);
|
||||
return ClientDisconnect_NoWriteExceptionThrown(ServerType.Kestrel);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
public void ClientDisconnect_WebListener_NoWriteExceptionThrown()
|
||||
public Task ClientDisconnect_WebListener_NoWriteExceptionThrown()
|
||||
{
|
||||
ClientDisconnect_NoWriteExceptionThrown(ServerType.HttpSys);
|
||||
return ClientDisconnect_NoWriteExceptionThrown(ServerType.HttpSys);
|
||||
}
|
||||
|
||||
private void ClientDisconnect_NoWriteExceptionThrown(ServerType serverType)
|
||||
private async Task ClientDisconnect_NoWriteExceptionThrown(ServerType serverType)
|
||||
{
|
||||
var interval = TimeSpan.FromSeconds(15);
|
||||
var requestReceived = new ManualResetEvent(false);
|
||||
var requestCancelled = new ManualResetEvent(false);
|
||||
var responseComplete = new ManualResetEvent(false);
|
||||
var requestReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var requestCancelled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var responseComplete = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
Exception exception = null;
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services => services.AddSingleton(LoggerFactory))
|
||||
|
|
@ -193,8 +194,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
{
|
||||
try
|
||||
{
|
||||
requestReceived.Set();
|
||||
Assert.True(requestCancelled.WaitOne(interval), "not cancelled");
|
||||
requestReceived.SetResult(0);
|
||||
await requestCancelled.Task.TimeoutAfter(interval);
|
||||
Assert.True(context.RequestAborted.WaitHandle.WaitOne(interval), "not aborted");
|
||||
await next();
|
||||
}
|
||||
|
|
@ -202,7 +203,7 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
{
|
||||
exception = ex;
|
||||
}
|
||||
responseComplete.Set();
|
||||
responseComplete.SetResult(0);
|
||||
});
|
||||
app.UseStaticFiles();
|
||||
});
|
||||
|
|
@ -220,13 +221,13 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
{
|
||||
// We don't use HttpClient here because it's disconnect behavior varies across platforms.
|
||||
var socket = SendSocketRequestAsync(server.GetAddress(), "/TestDocument1MB.txt");
|
||||
Assert.True(requestReceived.WaitOne(interval), "not received");
|
||||
await requestReceived.Task.TimeoutAfter(interval);
|
||||
|
||||
socket.LingerState = new LingerOption(true, 0);
|
||||
socket.Dispose();
|
||||
requestCancelled.Set();
|
||||
requestCancelled.SetResult(0);
|
||||
|
||||
Assert.True(responseComplete.WaitOne(interval), "not completed");
|
||||
await responseComplete.Task.TimeoutAfter(interval);
|
||||
Assert.Null(exception);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Mvc.ViewEngines;
|
|||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
|
@ -545,9 +546,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var id = "unique-id";
|
||||
var childContent = "some-content";
|
||||
var resetEvent1 = new ManualResetEvent(false);
|
||||
var resetEvent2 = new ManualResetEvent(false);
|
||||
var resetEvent3 = new ManualResetEvent(false);
|
||||
var event1 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var event2 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var event3 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var calls = 0;
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
|
||||
|
|
@ -560,7 +561,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
calls++;
|
||||
resetEvent2.Set();
|
||||
event2.SetResult(0);
|
||||
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetHtmlContent(childContent);
|
||||
|
|
@ -570,14 +571,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = new TagHelperOutput(
|
||||
"cache",
|
||||
new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
getChildContentAsync: async (useCachedResult, encoder) =>
|
||||
{
|
||||
calls++;
|
||||
resetEvent3.WaitOne(5000);
|
||||
await event3.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetHtmlContent(childContent);
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
return tagHelperContent;
|
||||
});
|
||||
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
|
|
@ -596,18 +597,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
var task1 = Task.Run(async () =>
|
||||
{
|
||||
resetEvent1.WaitOne(5000);
|
||||
await event1.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);
|
||||
resetEvent3.Set();
|
||||
event3.SetResult(0);
|
||||
});
|
||||
|
||||
var task2 = Task.Run(async () =>
|
||||
{
|
||||
resetEvent2.WaitOne(5000);
|
||||
await event2.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
await cacheTagHelper2.ProcessAsync(tagHelperContext1, tagHelperOutput2);
|
||||
});
|
||||
|
||||
resetEvent1.Set();
|
||||
event1.SetResult(0);
|
||||
await Task.WhenAll(task1, task2);
|
||||
|
||||
// Assert
|
||||
|
|
@ -630,9 +631,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var id = "unique-id";
|
||||
var childContent = "some-content";
|
||||
var resetEvent1 = new ManualResetEvent(false);
|
||||
var resetEvent2 = new ManualResetEvent(false);
|
||||
var resetEvent3 = new ManualResetEvent(false);
|
||||
var event1 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var event2 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var event3 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var calls = 0;
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
|
||||
|
|
@ -645,7 +646,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
calls++;
|
||||
resetEvent2.Set();
|
||||
event2.SetResult(0);
|
||||
|
||||
throw new Exception();
|
||||
});
|
||||
|
|
@ -653,14 +654,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = new TagHelperOutput(
|
||||
"cache",
|
||||
new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
getChildContentAsync: async (useCachedResult, encoder) =>
|
||||
{
|
||||
calls++;
|
||||
resetEvent3.WaitOne(5000);
|
||||
await event3.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetHtmlContent(childContent);
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
return tagHelperContent;
|
||||
});
|
||||
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
|
|
@ -679,18 +680,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
var task1 = Task.Run(async () =>
|
||||
{
|
||||
resetEvent1.WaitOne(5000);
|
||||
await event1.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
await Assert.ThrowsAsync<Exception>(() => cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1));
|
||||
resetEvent3.Set();
|
||||
event3.SetResult(0);
|
||||
});
|
||||
|
||||
var task2 = Task.Run(async () =>
|
||||
{
|
||||
resetEvent2.WaitOne(5000);
|
||||
await event2.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);
|
||||
});
|
||||
|
||||
resetEvent1.Set();
|
||||
event1.SetResult(0);
|
||||
await Task.WhenAll(task1, task2);
|
||||
|
||||
// Assert
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Mvc.ViewEngines;
|
|||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
|
@ -538,9 +539,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var childContent = "some-content";
|
||||
var resetEvent1 = new ManualResetEvent(false);
|
||||
var resetEvent2 = new ManualResetEvent(false);
|
||||
var resetEvent3 = new ManualResetEvent(false);
|
||||
var event1 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var event2 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var event3 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var calls = 0;
|
||||
var formatter = GetFormatter();
|
||||
var storage = GetStorage();
|
||||
|
|
@ -559,7 +560,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
calls++;
|
||||
resetEvent2.Set();
|
||||
event2.SetResult(0);
|
||||
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetHtmlContent(childContent);
|
||||
|
|
@ -569,14 +570,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = new TagHelperOutput(
|
||||
"distributed-cache",
|
||||
new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
getChildContentAsync: async (useCachedResult, encoder) =>
|
||||
{
|
||||
calls++;
|
||||
resetEvent3.WaitOne(5000);
|
||||
await event3.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetHtmlContent(childContent);
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
return tagHelperContent;
|
||||
});
|
||||
|
||||
var cacheTagHelper1 = new DistributedCacheTagHelper(
|
||||
|
|
@ -599,18 +600,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
var task1 = Task.Run(async () =>
|
||||
{
|
||||
resetEvent1.WaitOne(5000);
|
||||
await event1.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);
|
||||
resetEvent3.Set();
|
||||
event3.SetResult(0);
|
||||
});
|
||||
|
||||
var task2 = Task.Run(async () =>
|
||||
{
|
||||
resetEvent2.WaitOne(5000);
|
||||
await event2.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
await cacheTagHelper2.ProcessAsync(tagHelperContext1, tagHelperOutput2);
|
||||
});
|
||||
|
||||
resetEvent1.Set();
|
||||
event1.SetResult(0);
|
||||
await Task.WhenAll(task1, task2);
|
||||
|
||||
// Assert
|
||||
|
|
@ -632,9 +633,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var childContent = "some-content";
|
||||
var resetEvent1 = new ManualResetEvent(false);
|
||||
var resetEvent2 = new ManualResetEvent(false);
|
||||
var resetEvent3 = new ManualResetEvent(false);
|
||||
var event1 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var event2 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var event3 = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var calls = 0;
|
||||
var formatter = GetFormatter();
|
||||
var storage = GetStorage();
|
||||
|
|
@ -653,7 +654,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
calls++;
|
||||
resetEvent2.Set();
|
||||
event2.SetResult(0);
|
||||
|
||||
throw new Exception();
|
||||
});
|
||||
|
|
@ -661,14 +662,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = new TagHelperOutput(
|
||||
"distributed-cache",
|
||||
new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
getChildContentAsync: async (useCachedResult, encoder) =>
|
||||
{
|
||||
calls++;
|
||||
resetEvent3.WaitOne(5000);
|
||||
await event3.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetHtmlContent(childContent);
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
return tagHelperContent;
|
||||
});
|
||||
|
||||
var cacheTagHelper1 = new DistributedCacheTagHelper(
|
||||
|
|
@ -691,18 +692,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
var task1 = Task.Run(async () =>
|
||||
{
|
||||
resetEvent1.WaitOne(5000);
|
||||
await event1.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
await Assert.ThrowsAsync<Exception>(() => cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1));
|
||||
resetEvent3.Set();
|
||||
event3.SetResult(0);
|
||||
});
|
||||
|
||||
var task2 = Task.Run(async () =>
|
||||
{
|
||||
resetEvent2.WaitOne(5000);
|
||||
await event2.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);
|
||||
});
|
||||
|
||||
resetEvent1.Set();
|
||||
event1.SetResult(0);
|
||||
await Task.WhenAll(task1, task2);
|
||||
|
||||
// Assert
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.Net.Http;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -167,7 +168,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
[ConditionalFact]
|
||||
public async Task AuthTypes_AccessUserInOnCompleted_Success()
|
||||
{
|
||||
var completed = new ManualResetEvent(false);
|
||||
var completed = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
string userName = null;
|
||||
var authTypes = AuthenticationSchemes.Negotiate | AuthenticationSchemes.NTLM;
|
||||
using (var server = Utilities.CreateDynamicHost(authTypes, DenyAnoymous, out var address, httpContext =>
|
||||
|
|
@ -178,7 +179,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
httpContext.Response.OnCompleted(() =>
|
||||
{
|
||||
userName = httpContext.User.Identity.Name;
|
||||
completed.Set();
|
||||
completed.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
return Task.FromResult(0);
|
||||
|
|
@ -186,7 +187,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
{
|
||||
var response = await SendRequestAsync(address, useDefaultCredentials: true);
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.True(completed.WaitOne(TimeSpan.FromSeconds(5)));
|
||||
await completed.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
Assert.False(string.IsNullOrEmpty(userName));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using System.Net.Sockets;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
public async Task Server_TokenRegisteredAfterClientDisconnects_CallCanceled()
|
||||
{
|
||||
var interval = TimeSpan.FromSeconds(1);
|
||||
var canceled = new ManualResetEvent(false);
|
||||
var canceled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
|
|
@ -36,11 +37,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
var ct = context.DisconnectToken;
|
||||
Assert.True(ct.CanBeCanceled, "CanBeCanceled");
|
||||
ct.Register(() => canceled.Set());
|
||||
ct.Register(() => canceled.SetResult(0));
|
||||
Assert.True(ct.WaitHandle.WaitOne(interval));
|
||||
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
|
||||
Assert.True(canceled.WaitOne(interval), "canceled");
|
||||
await canceled.Task.TimeoutAfter(interval);
|
||||
|
||||
context.Dispose();
|
||||
}
|
||||
|
|
@ -51,7 +52,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
public async Task Server_TokenRegisteredAfterResponseSent_Success()
|
||||
{
|
||||
var interval = TimeSpan.FromSeconds(1);
|
||||
var canceled = new ManualResetEvent(false);
|
||||
var canceled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
|
|
@ -69,11 +70,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
var ct = context.DisconnectToken;
|
||||
Assert.False(ct.CanBeCanceled, "CanBeCanceled");
|
||||
ct.Register(() => canceled.Set());
|
||||
ct.Register(() => canceled.SetResult(0));
|
||||
Assert.False(ct.WaitHandle.WaitOne(interval));
|
||||
Assert.False(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
|
||||
Assert.False(canceled.WaitOne(interval), "canceled");
|
||||
Assert.False(canceled.Task.IsCompleted, "canceled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +83,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
public async Task Server_ConnectionCloseHeader_CancellationTokenFires()
|
||||
{
|
||||
var interval = TimeSpan.FromSeconds(1);
|
||||
var canceled = new ManualResetEvent(false);
|
||||
var canceled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address))
|
||||
|
|
@ -93,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
var ct = context.DisconnectToken;
|
||||
Assert.True(ct.CanBeCanceled, "CanBeCanceled");
|
||||
Assert.False(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
ct.Register(() => canceled.Set());
|
||||
ct.Register(() => canceled.SetResult(0));
|
||||
|
||||
context.Response.Headers["Connection"] = "close";
|
||||
|
||||
|
|
@ -102,7 +103,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
await writer.WriteAsync("Hello World");
|
||||
await writer.FlushAsync();
|
||||
|
||||
Assert.True(canceled.WaitOne(interval), "Disconnected");
|
||||
await canceled.Task.TimeoutAfter(interval);
|
||||
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
|
||||
var response = await responseTask;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -104,25 +105,20 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
|
||||
public async Task OpaqueUpgrade_GetUpgrade_Success()
|
||||
{
|
||||
ManualResetEvent waitHandle = new ManualResetEvent(false);
|
||||
bool? upgraded = null;
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, async httpContext =>
|
||||
var upgraded = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
httpContext.Response.Headers["Upgrade"] = "websocket"; // Win8.1 blocks anything but WebSockets
|
||||
var opaqueFeature = httpContext.Features.Get<IHttpUpgradeFeature>();
|
||||
Assert.NotNull(opaqueFeature);
|
||||
Assert.True(opaqueFeature.IsUpgradableRequest);
|
||||
await opaqueFeature.UpgradeAsync();
|
||||
upgraded = true;
|
||||
waitHandle.Set();
|
||||
upgraded.SetResult(true);
|
||||
}))
|
||||
{
|
||||
using (Stream stream = await SendOpaqueRequestAsync("GET", address))
|
||||
{
|
||||
Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(1)), "Timed out");
|
||||
Assert.True(upgraded.HasValue, "Upgraded not set");
|
||||
Assert.True(upgraded.Value, "Upgrade failed");
|
||||
Assert.True(await upgraded.Task.TimeoutAfter(TimeSpan.FromSeconds(1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -131,10 +127,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
|
||||
public async Task OpaqueUpgrade_GetUpgrade_NotAffectedByMaxRequestBodyLimit()
|
||||
{
|
||||
ManualResetEvent waitHandle = new ManualResetEvent(false);
|
||||
bool? upgraded = null;
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, async httpContext =>
|
||||
var upgraded = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
var feature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
|
||||
Assert.NotNull(feature);
|
||||
|
|
@ -150,16 +144,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.Null(feature.MaxRequestBodySize);
|
||||
Assert.Throws<InvalidOperationException>(() => feature.MaxRequestBodySize = 12);
|
||||
Assert.Equal(15, await stream.ReadAsync(new byte[15], 0, 15));
|
||||
upgraded = true;
|
||||
waitHandle.Set();
|
||||
upgraded.SetResult(true);
|
||||
}, options => options.MaxRequestBodySize = 10))
|
||||
{
|
||||
using (Stream stream = await SendOpaqueRequestAsync("GET", address))
|
||||
{
|
||||
stream.Write(new byte[15], 0, 15);
|
||||
Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(10)), "Timed out");
|
||||
Assert.True(upgraded.HasValue, "Upgraded not set");
|
||||
Assert.True(upgraded.Value, "Upgrade failed");
|
||||
Assert.True(await upgraded.Task.TimeoutAfter(TimeSpan.FromSeconds(10)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -169,10 +160,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task OpaqueUpgrade_WithOnStarting_CallbackCalled()
|
||||
{
|
||||
var callbackCalled = false;
|
||||
var waitHandle = new ManualResetEvent(false);
|
||||
bool? upgraded = null;
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, async httpContext =>
|
||||
var upgraded = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
httpContext.Response.OnStarting(_ =>
|
||||
{
|
||||
|
|
@ -184,15 +173,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.NotNull(opaqueFeature);
|
||||
Assert.True(opaqueFeature.IsUpgradableRequest);
|
||||
await opaqueFeature.UpgradeAsync();
|
||||
upgraded = true;
|
||||
waitHandle.Set();
|
||||
upgraded.SetResult(true);
|
||||
}))
|
||||
{
|
||||
using (Stream stream = await SendOpaqueRequestAsync("GET", address))
|
||||
{
|
||||
Assert.True(waitHandle.WaitOne(TimeSpan.FromSeconds(1)), "Timed out");
|
||||
Assert.True(upgraded.HasValue, "Upgraded not set");
|
||||
Assert.True(upgraded.Value, "Upgrade failed");
|
||||
Assert.True(await upgraded.Task.TimeoutAfter(TimeSpan.FromSeconds(1)));
|
||||
Assert.True(callbackCalled, "Callback not called");
|
||||
}
|
||||
}
|
||||
|
|
@ -364,4 +350,4 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -157,10 +158,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
[ConditionalFact]
|
||||
public async Task ResponseBody_WriteContentLengthExtraWritten_Throws()
|
||||
{
|
||||
var waitHandle = new ManualResetEvent(false);
|
||||
bool? appThrew = null;
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var requestThrew = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (Utilities.CreateHttpServer(out var address, httpContext =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -168,13 +167,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
httpContext.Response.Headers["Content-lenGth"] = " 10 ";
|
||||
httpContext.Response.Body.Write(new byte[10], 0, 10);
|
||||
httpContext.Response.Body.Write(new byte[9], 0, 9);
|
||||
appThrew = false;
|
||||
requestThrew.SetResult(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
appThrew = true;
|
||||
requestThrew.SetResult(true);
|
||||
}
|
||||
waitHandle.Set();
|
||||
return Task.FromResult(0);
|
||||
}))
|
||||
{
|
||||
|
|
@ -188,9 +186,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.Null(response.Headers.TransferEncodingChunked);
|
||||
Assert.Equal(new byte[10], await response.Content.ReadAsByteArrayAsync());
|
||||
|
||||
Assert.True(waitHandle.WaitOne(100));
|
||||
Assert.True(appThrew.HasValue, "appThrew.HasValue");
|
||||
Assert.True(appThrew.Value, "appThrew.Value");
|
||||
Assert.True(await requestThrew.Task.TimeoutAfter(TimeSpan.FromSeconds(10)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -74,34 +75,26 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
[ConditionalFact]
|
||||
public async Task ResponseSendFile_MissingFile_Throws()
|
||||
{
|
||||
var waitHandle = new ManualResetEvent(false);
|
||||
bool? appThrew = null;
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var appThrew = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (Utilities.CreateHttpServer(out var address, httpContext =>
|
||||
{
|
||||
var sendFile = httpContext.Features.Get<IHttpSendFileFeature>();
|
||||
try
|
||||
{
|
||||
sendFile.SendFileAsync(string.Empty, 0, null, CancellationToken.None).Wait();
|
||||
appThrew = false;
|
||||
appThrew.SetResult(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
appThrew = true;
|
||||
appThrew.SetResult(true);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
waitHandle.Set();
|
||||
}
|
||||
return Task.FromResult(0);
|
||||
}))
|
||||
{
|
||||
HttpResponseMessage response = await SendRequestAsync(address);
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
Assert.True(waitHandle.WaitOne(100));
|
||||
Assert.True(appThrew.HasValue, "appThrew.HasValue");
|
||||
Assert.True(appThrew.Value, "appThrew.Value");
|
||||
Assert.True(await appThrew.Task.TimeoutAfter(TimeSpan.FromSeconds(10)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.Net.Http;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -123,21 +124,21 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
[ConditionalFact]
|
||||
public async Task Response_Empty_CallsOnStartingAndOnCompleted()
|
||||
{
|
||||
var onStartingCalled = new ManualResetEvent(false);
|
||||
var onCompletedCalled = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var onStartingCalled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var onCompletedCalled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
using (Utilities.CreateHttpServer(out var address, httpContext =>
|
||||
{
|
||||
httpContext.Response.OnStarting(state =>
|
||||
{
|
||||
Assert.Same(state, httpContext);
|
||||
onStartingCalled.Set();
|
||||
onStartingCalled.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
}, httpContext);
|
||||
httpContext.Response.OnCompleted(state =>
|
||||
{
|
||||
Assert.Same(state, httpContext);
|
||||
onCompletedCalled.Set();
|
||||
onCompletedCalled.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
}, httpContext);
|
||||
return Task.FromResult(0);
|
||||
|
|
@ -145,29 +146,28 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
{
|
||||
var response = await SendRequestAsync(address);
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.True(onStartingCalled.WaitOne(0));
|
||||
await onStartingCalled.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
|
||||
// Fires after the response completes
|
||||
Assert.True(onCompletedCalled.WaitOne(TimeSpan.FromSeconds(5)));
|
||||
await onCompletedCalled.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Response_OnStartingThrows_StillCallsOnCompleted()
|
||||
{
|
||||
var onStartingCalled = new ManualResetEvent(false);
|
||||
var onCompletedCalled = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var onStartingCalled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var onCompletedCalled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (Utilities.CreateHttpServer(out var address, httpContext =>
|
||||
{
|
||||
httpContext.Response.OnStarting(state =>
|
||||
{
|
||||
onStartingCalled.Set();
|
||||
onStartingCalled.SetResult(0);
|
||||
throw new Exception("Failed OnStarting");
|
||||
}, httpContext);
|
||||
httpContext.Response.OnCompleted(state =>
|
||||
{
|
||||
Assert.Same(state, httpContext);
|
||||
onCompletedCalled.Set();
|
||||
onCompletedCalled.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
}, httpContext);
|
||||
return Task.FromResult(0);
|
||||
|
|
@ -175,29 +175,28 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
{
|
||||
var response = await SendRequestAsync(address);
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
Assert.True(onStartingCalled.WaitOne(0));
|
||||
await onStartingCalled.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
|
||||
// Fires after the response completes
|
||||
Assert.True(onCompletedCalled.WaitOne(TimeSpan.FromSeconds(5)));
|
||||
await onCompletedCalled.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Response_OnStartingThrowsAfterWrite_WriteThrowsAndStillCallsOnCompleted()
|
||||
{
|
||||
var onStartingCalled = new ManualResetEvent(false);
|
||||
var onCompletedCalled = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var onStartingCalled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var onCompletedCalled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (Utilities.CreateHttpServer(out var address, httpContext =>
|
||||
{
|
||||
httpContext.Response.OnStarting(state =>
|
||||
{
|
||||
onStartingCalled.Set();
|
||||
onStartingCalled.SetResult(0);
|
||||
throw new InvalidTimeZoneException("Failed OnStarting");
|
||||
}, httpContext);
|
||||
httpContext.Response.OnCompleted(state =>
|
||||
{
|
||||
Assert.Same(state, httpContext);
|
||||
onCompletedCalled.Set();
|
||||
onCompletedCalled.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
}, httpContext);
|
||||
Assert.Throws<InvalidTimeZoneException>(() => httpContext.Response.Body.Write(new byte[10], 0, 10));
|
||||
|
|
@ -206,9 +205,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
{
|
||||
var response = await SendRequestAsync(address);
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.True(onStartingCalled.WaitOne(0));
|
||||
await onStartingCalled.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
|
||||
// Fires after the response completes
|
||||
Assert.True(onCompletedCalled.WaitOne(TimeSpan.FromSeconds(5)));
|
||||
await onCompletedCalled.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,17 +69,16 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task Server_ShutdownDuringRequest_Success()
|
||||
{
|
||||
Task<string> responseTask;
|
||||
ManualResetEvent received = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (var server = Utilities.CreateHttpServer(out var address, httpContext =>
|
||||
{
|
||||
received.Set();
|
||||
received.SetResult(0);
|
||||
httpContext.Response.ContentLength = 11;
|
||||
return httpContext.Response.WriteAsync("Hello World");
|
||||
}))
|
||||
{
|
||||
responseTask = SendRequestAsync(address);
|
||||
Assert.True(received.WaitOne(10000));
|
||||
await received.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
await server.StopAsync(new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token);
|
||||
}
|
||||
string response = await responseTask;
|
||||
|
|
@ -90,21 +89,20 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task Server_DisposeWithoutStopDuringRequest_Aborts()
|
||||
{
|
||||
Task<string> responseTask;
|
||||
var received = new ManualResetEvent(false);
|
||||
var stopped = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var stopped = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (var server = Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
received.Set();
|
||||
Assert.True(stopped.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
received.SetResult(0);
|
||||
await stopped.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
httpContext.Response.ContentLength = 11;
|
||||
return httpContext.Response.WriteAsync("Hello World");
|
||||
await httpContext.Response.WriteAsync("Hello World");
|
||||
}))
|
||||
{
|
||||
responseTask = SendRequestAsync(address);
|
||||
Assert.True(received.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
await received.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
}
|
||||
stopped.Set();
|
||||
stopped.SetResult(0);
|
||||
await Assert.ThrowsAsync<HttpRequestException>(async () => await responseTask);
|
||||
}
|
||||
|
||||
|
|
@ -112,24 +110,21 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task Server_ShutdownDuringLongRunningRequest_TimesOut()
|
||||
{
|
||||
Task<string> responseTask;
|
||||
var received = new ManualResetEvent(false);
|
||||
bool? shutdown = null;
|
||||
var waitForShutdown = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var shutdown = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (var server = Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
received.Set();
|
||||
shutdown = waitForShutdown.WaitOne(TimeSpan.FromSeconds(15));
|
||||
received.SetResult(0);
|
||||
await shutdown.Task.TimeoutAfter(TimeSpan.FromSeconds(15));
|
||||
httpContext.Response.ContentLength = 11;
|
||||
return httpContext.Response.WriteAsync("Hello World");
|
||||
await httpContext.Response.WriteAsync("Hello World");
|
||||
}))
|
||||
{
|
||||
responseTask = SendRequestAsync(address);
|
||||
Assert.True(received.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
Assert.False(shutdown.HasValue);
|
||||
await received.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
await server.StopAsync(new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token);
|
||||
}
|
||||
waitForShutdown.Set();
|
||||
shutdown.SetResult(0);
|
||||
await Assert.ThrowsAsync<HttpRequestException>(async () => await responseTask);
|
||||
}
|
||||
|
||||
|
|
@ -217,64 +212,59 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
[ConditionalFact]
|
||||
public async Task Server_ClientDisconnects_CallCanceled()
|
||||
{
|
||||
TimeSpan interval = TimeSpan.FromSeconds(10);
|
||||
ManualResetEvent received = new ManualResetEvent(false);
|
||||
ManualResetEvent aborted = new ManualResetEvent(false);
|
||||
ManualResetEvent canceled = new ManualResetEvent(false);
|
||||
var interval = TimeSpan.FromSeconds(10);
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var aborted = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var canceled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||
using (Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
CancellationToken ct = httpContext.RequestAborted;
|
||||
var ct = httpContext.RequestAborted;
|
||||
Assert.True(ct.CanBeCanceled, "CanBeCanceled");
|
||||
Assert.False(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
ct.Register(() => canceled.Set());
|
||||
received.Set();
|
||||
Assert.True(aborted.WaitOne(interval), "Aborted");
|
||||
ct.Register(() => canceled.SetResult(0));
|
||||
received.SetResult(0);
|
||||
await aborted.Task.TimeoutAfter(interval);
|
||||
Assert.True(ct.WaitHandle.WaitOne(interval), "CT Wait");
|
||||
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
return Task.FromResult(0);
|
||||
}))
|
||||
{
|
||||
// Note: System.Net.Sockets does not RST the connection by default, it just FINs.
|
||||
// Http.Sys's disconnect notice requires a RST.
|
||||
using (var client = await SendHungRequestAsync("GET", address))
|
||||
{
|
||||
Assert.True(received.WaitOne(interval), "Receive Timeout");
|
||||
await received.Task.TimeoutAfter(interval);
|
||||
|
||||
// Force a RST
|
||||
client.LingerState = new LingerOption(true, 0);
|
||||
}
|
||||
aborted.Set();
|
||||
Assert.True(canceled.WaitOne(interval), "canceled");
|
||||
aborted.SetResult(0);
|
||||
await canceled.Task.TimeoutAfter(interval);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Server_Abort_CallCanceled()
|
||||
{
|
||||
TimeSpan interval = TimeSpan.FromSeconds(100);
|
||||
ManualResetEvent received = new ManualResetEvent(false);
|
||||
ManualResetEvent aborted = new ManualResetEvent(false);
|
||||
ManualResetEvent canceled = new ManualResetEvent(false);
|
||||
var interval = TimeSpan.FromSeconds(10);
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var canceled = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||
using (Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
CancellationToken ct = httpContext.RequestAborted;
|
||||
Assert.True(ct.CanBeCanceled, "CanBeCanceled");
|
||||
Assert.False(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
ct.Register(() => canceled.Set());
|
||||
received.Set();
|
||||
ct.Register(() => canceled.SetResult(0));
|
||||
received.SetResult(0);
|
||||
httpContext.Abort();
|
||||
Assert.True(canceled.WaitOne(interval), "Aborted");
|
||||
await canceled.Task.TimeoutAfter(interval);
|
||||
Assert.True(ct.IsCancellationRequested, "IsCancellationRequested");
|
||||
return Task.FromResult(0);
|
||||
}))
|
||||
{
|
||||
using (var client = await SendHungRequestAsync("GET", address))
|
||||
{
|
||||
Assert.True(received.WaitOne(interval), "Receive Timeout");
|
||||
await received.Task.TimeoutAfter(interval);
|
||||
Assert.Throws<IOException>(() => client.GetStream().Read(new byte[10], 0, 10));
|
||||
}
|
||||
}
|
||||
|
|
@ -423,19 +413,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task Server_MultipleStopAsyncCallsWaitForRequestsToDrain_Success()
|
||||
{
|
||||
Task<string> responseTask;
|
||||
ManualResetEvent received = new ManualResetEvent(false);
|
||||
ManualResetEvent run = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var run = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (var server = Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
received.Set();
|
||||
Assert.True(run.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
received.SetResult(0);
|
||||
await run.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
httpContext.Response.ContentLength = 11;
|
||||
return httpContext.Response.WriteAsync("Hello World");
|
||||
await httpContext.Response.WriteAsync("Hello World");
|
||||
}))
|
||||
{
|
||||
responseTask = SendRequestAsync(address);
|
||||
Assert.True(received.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
await received.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
|
||||
var stopTask1 = server.StopAsync(cts.Token);
|
||||
|
|
@ -446,11 +435,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
Assert.False(stopTask2.IsCompleted);
|
||||
Assert.False(stopTask3.IsCompleted);
|
||||
|
||||
run.Set();
|
||||
run.SetResult(0);
|
||||
|
||||
await Task.WhenAll(stopTask1, stopTask2, stopTask3).TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
}
|
||||
string response = await responseTask;
|
||||
var response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
}
|
||||
|
||||
|
|
@ -458,19 +447,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task Server_MultipleStopAsyncCallsCompleteOnCancellation_SameToken_Success()
|
||||
{
|
||||
Task<string> responseTask;
|
||||
ManualResetEvent received = new ManualResetEvent(false);
|
||||
ManualResetEvent run = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var run = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (var server = Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
received.Set();
|
||||
Assert.True(run.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
received.SetResult(0);
|
||||
await run.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
httpContext.Response.ContentLength = 11;
|
||||
return httpContext.Response.WriteAsync("Hello World");
|
||||
await httpContext.Response.WriteAsync("Hello World");
|
||||
}))
|
||||
{
|
||||
responseTask = SendRequestAsync(address);
|
||||
Assert.True(received.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
await received.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
var stopTask1 = server.StopAsync(cts.Token);
|
||||
|
|
@ -485,7 +473,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
|
||||
await Task.WhenAll(stopTask1, stopTask2, stopTask3).TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
run.Set();
|
||||
run.SetResult(0);
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
|
|
@ -496,19 +484,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task Server_MultipleStopAsyncCallsCompleteOnSingleCancellation_FirstToken_Success()
|
||||
{
|
||||
Task<string> responseTask;
|
||||
ManualResetEvent received = new ManualResetEvent(false);
|
||||
ManualResetEvent run = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var run = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (var server = Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
received.Set();
|
||||
Assert.True(run.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
received.SetResult(0);
|
||||
await run.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
httpContext.Response.ContentLength = 11;
|
||||
return httpContext.Response.WriteAsync("Hello World");
|
||||
await httpContext.Response.WriteAsync("Hello World");
|
||||
}))
|
||||
{
|
||||
responseTask = SendRequestAsync(address);
|
||||
Assert.True(received.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
await received.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
var stopTask1 = server.StopAsync(cts.Token);
|
||||
|
|
@ -523,7 +510,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
|
||||
await Task.WhenAll(stopTask1, stopTask2, stopTask3).TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
run.Set();
|
||||
run.SetResult(0);
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
|
|
@ -534,19 +521,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task Server_MultipleStopAsyncCallsCompleteOnSingleCancellation_SubsequentToken_Success()
|
||||
{
|
||||
Task<string> responseTask;
|
||||
ManualResetEvent received = new ManualResetEvent(false);
|
||||
ManualResetEvent run = new ManualResetEvent(false);
|
||||
string address;
|
||||
using (var server = Utilities.CreateHttpServer(out address, httpContext =>
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var run = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (var server = Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
received.Set();
|
||||
Assert.True(run.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
received.SetResult(0);
|
||||
await run.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
httpContext.Response.ContentLength = 11;
|
||||
return httpContext.Response.WriteAsync("Hello World");
|
||||
await httpContext.Response.WriteAsync("Hello World");
|
||||
}))
|
||||
{
|
||||
responseTask = SendRequestAsync(address);
|
||||
Assert.True(received.WaitOne(10000));
|
||||
await received.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
var stopTask1 = server.StopAsync(new CancellationTokenSource().Token);
|
||||
|
|
@ -561,7 +547,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
|
||||
await Task.WhenAll(stopTask1, stopTask2, stopTask3).TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
run.Set();
|
||||
run.SetResult(0);
|
||||
|
||||
string response = await responseTask;
|
||||
Assert.Equal("Hello World", response);
|
||||
|
|
@ -572,21 +558,20 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public async Task Server_DisposeContinuesPendingStopAsyncCalls()
|
||||
{
|
||||
Task<string> responseTask;
|
||||
ManualResetEvent received = new ManualResetEvent(false);
|
||||
ManualResetEvent run = new ManualResetEvent(false);
|
||||
string address;
|
||||
var received = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var run = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
Task stopTask1;
|
||||
Task stopTask2;
|
||||
using (var server = Utilities.CreateHttpServer(out address, httpContext =>
|
||||
using (var server = Utilities.CreateHttpServer(out var address, async httpContext =>
|
||||
{
|
||||
received.Set();
|
||||
Assert.True(run.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
received.SetResult(0);
|
||||
await run.Task.TimeoutAfter(TimeSpan.FromSeconds(15));
|
||||
httpContext.Response.ContentLength = 11;
|
||||
return httpContext.Response.WriteAsync("Hello World");
|
||||
await httpContext.Response.WriteAsync("Hello World");
|
||||
}))
|
||||
{
|
||||
responseTask = SendRequestAsync(address);
|
||||
Assert.True(received.WaitOne(TimeSpan.FromSeconds(10)));
|
||||
await received.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
stopTask1 = server.StopAsync(new CancellationTokenSource().Token);
|
||||
stopTask2 = server.StopAsync(new CancellationTokenSource().Token);
|
||||
|
|
@ -596,6 +581,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
}
|
||||
|
||||
await Task.WhenAll(stopTask1, stopTask2).TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
run.SetResult(0);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Hosting;
|
|||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
@ -160,37 +161,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
return server;
|
||||
}
|
||||
|
||||
internal static Task WithTimeout(this Task task) => task.WithTimeout(DefaultTimeout);
|
||||
internal static Task WithTimeout(this Task task) => task.TimeoutAfter(DefaultTimeout);
|
||||
|
||||
internal static async Task WithTimeout(this Task task, TimeSpan timeout)
|
||||
{
|
||||
var completedTask = await Task.WhenAny(task, Task.Delay(timeout));
|
||||
|
||||
if (completedTask == task)
|
||||
{
|
||||
await task;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TimeoutException("The task has timed out.");
|
||||
}
|
||||
}
|
||||
|
||||
internal static Task<T> WithTimeout<T>(this Task<T> task) => task.WithTimeout(DefaultTimeout);
|
||||
|
||||
internal static async Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout)
|
||||
{
|
||||
var completedTask = await Task.WhenAny(task, Task.Delay(timeout));
|
||||
|
||||
if (completedTask == task)
|
||||
{
|
||||
return await task;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TimeoutException("The task has timed out.");
|
||||
}
|
||||
}
|
||||
internal static Task<T> WithTimeout<T>(this Task<T> task) => task.TimeoutAfter(DefaultTimeout);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -81,8 +82,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
[InlineData("/pathBase", "/pathBase/iisintegration", "Shutdown")]
|
||||
public async Task MiddlewareShutsdownGivenANCMShutdown(string pathBase, string requestPath, string shutdownEvent)
|
||||
{
|
||||
var requestExecuted = new ManualResetEvent(false);
|
||||
var applicationStoppingFired = new ManualResetEvent(false);
|
||||
var requestExecuted = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var applicationStoppingFired = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var builder = new WebHostBuilder()
|
||||
.UseSetting("TOKEN", "TestToken")
|
||||
.UseSetting("PORT", "12345")
|
||||
|
|
@ -91,11 +92,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
.Configure(app =>
|
||||
{
|
||||
var appLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
|
||||
appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.Set());
|
||||
appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.SetResult(0));
|
||||
|
||||
app.Run(context =>
|
||||
{
|
||||
requestExecuted.Set();
|
||||
requestExecuted.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
|
|
@ -106,8 +107,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", shutdownEvent);
|
||||
var response = await server.CreateClient().SendAsync(request);
|
||||
|
||||
Assert.True(applicationStoppingFired.WaitOne(TimeSpan.FromSeconds(5)));
|
||||
Assert.False(requestExecuted.WaitOne(0));
|
||||
await applicationStoppingFired.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
|
||||
Assert.False(requestExecuted.Task.IsCompleted);
|
||||
Assert.Equal(HttpStatusCode.Accepted, response.StatusCode);
|
||||
}
|
||||
|
||||
|
|
@ -131,8 +132,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
[MemberData(nameof(InvalidShutdownMethods))]
|
||||
public async Task MiddlewareIgnoresShutdownGivenWrongMethod(HttpMethod method)
|
||||
{
|
||||
var requestExecuted = new ManualResetEvent(false);
|
||||
var applicationStoppingFired = new ManualResetEvent(false);
|
||||
var requestExecuted = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var applicationStoppingFired = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var builder = new WebHostBuilder()
|
||||
.UseSetting("TOKEN", "TestToken")
|
||||
.UseSetting("PORT", "12345")
|
||||
|
|
@ -141,11 +142,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
.Configure(app =>
|
||||
{
|
||||
var appLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
|
||||
appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.Set());
|
||||
appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.SetResult(0));
|
||||
|
||||
app.Run(context =>
|
||||
{
|
||||
requestExecuted.Set();
|
||||
requestExecuted.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
|
|
@ -156,8 +157,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", "shutdown");
|
||||
var response = await server.CreateClient().SendAsync(request);
|
||||
|
||||
Assert.False(applicationStoppingFired.WaitOne(TimeSpan.FromSeconds(1)));
|
||||
Assert.True(requestExecuted.WaitOne(0));
|
||||
Assert.False(applicationStoppingFired.Task.IsCompleted);
|
||||
await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
|
||||
|
|
@ -167,8 +168,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
[InlineData("/path/iisintegration")]
|
||||
public async Task MiddlewareIgnoresShutdownGivenWrongPath(string path)
|
||||
{
|
||||
var requestExecuted = new ManualResetEvent(false);
|
||||
var applicationStoppingFired = new ManualResetEvent(false);
|
||||
var requestExecuted = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var applicationStoppingFired = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var builder = new WebHostBuilder()
|
||||
.UseSetting("TOKEN", "TestToken")
|
||||
.UseSetting("PORT", "12345")
|
||||
|
|
@ -177,11 +178,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
.Configure(app =>
|
||||
{
|
||||
var appLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
|
||||
appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.Set());
|
||||
appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.SetResult(0));
|
||||
|
||||
app.Run(context =>
|
||||
{
|
||||
requestExecuted.Set();
|
||||
requestExecuted.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
|
|
@ -192,8 +193,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", "shutdown");
|
||||
var response = await server.CreateClient().SendAsync(request);
|
||||
|
||||
Assert.False(applicationStoppingFired.WaitOne(TimeSpan.FromSeconds(1)));
|
||||
Assert.True(requestExecuted.WaitOne(0));
|
||||
Assert.False(applicationStoppingFired.Task.IsCompleted);
|
||||
await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
|
||||
|
|
@ -203,8 +204,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
[InlineData(null)]
|
||||
public async Task MiddlewareIgnoresShutdownGivenWrongEvent(string shutdownEvent)
|
||||
{
|
||||
var requestExecuted = new ManualResetEvent(false);
|
||||
var applicationStoppingFired = new ManualResetEvent(false);
|
||||
var requestExecuted = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var applicationStoppingFired = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var builder = new WebHostBuilder()
|
||||
.UseSetting("TOKEN", "TestToken")
|
||||
.UseSetting("PORT", "12345")
|
||||
|
|
@ -213,11 +214,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
.Configure(app =>
|
||||
{
|
||||
var appLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
|
||||
appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.Set());
|
||||
appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.SetResult(0));
|
||||
|
||||
app.Run(context =>
|
||||
{
|
||||
requestExecuted.Set();
|
||||
requestExecuted.SetResult(0);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
|
|
@ -228,8 +229,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", shutdownEvent);
|
||||
var response = await server.CreateClient().SendAsync(request);
|
||||
|
||||
Assert.False(applicationStoppingFired.WaitOne(TimeSpan.FromSeconds(1)));
|
||||
Assert.True(requestExecuted.WaitOne(0));
|
||||
Assert.False(applicationStoppingFired.Task.IsCompleted);
|
||||
await requestExecuted.Task.TimeoutAfter(TimeSpan.FromSeconds(1));
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.DotNet.Watcher.Internal;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
|
@ -19,32 +21,33 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
_output = output;
|
||||
}
|
||||
|
||||
private const int DefaultTimeout = 10 * 1000; // 10 sec
|
||||
private readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(60);
|
||||
private readonly TimeSpan NegativeTimeout = TimeSpan.FromSeconds(5);
|
||||
private readonly ITestOutputHelper _output;
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void NewFile(bool usePolling)
|
||||
public async Task NewFile(bool usePolling)
|
||||
{
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
using (var changedEv = new ManualResetEvent(false))
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var filesChanged = new HashSet<string>();
|
||||
|
||||
watcher.OnFileChange += (_, f) =>
|
||||
{
|
||||
filesChanged.Add(f);
|
||||
changedEv.Set();
|
||||
changedEv.TrySetResult(0);
|
||||
};
|
||||
watcher.EnableRaisingEvents = true;
|
||||
|
||||
var testFileFullPath = Path.Combine(dir, "foo");
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
await changedEv.Task.TimeoutAfter(DefaultTimeout);
|
||||
Assert.Equal(testFileFullPath, filesChanged.Single());
|
||||
}
|
||||
});
|
||||
|
|
@ -53,16 +56,16 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void ChangeFile(bool usePolling)
|
||||
public async Task ChangeFile(bool usePolling)
|
||||
{
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
var testFileFullPath = Path.Combine(dir, "foo");
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
using (var changedEv = new ManualResetEvent(false))
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var filesChanged = new HashSet<string>();
|
||||
|
||||
EventHandler<string> handler = null;
|
||||
|
|
@ -72,7 +75,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
watcher.OnFileChange -= handler;
|
||||
|
||||
filesChanged.Add(f);
|
||||
changedEv.Set();
|
||||
changedEv.TrySetResult(0);
|
||||
};
|
||||
|
||||
watcher.OnFileChange += handler;
|
||||
|
|
@ -81,10 +84,10 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
await Task.Delay(1000);
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
await changedEv.Task.TimeoutAfter(DefaultTimeout);
|
||||
Assert.Equal(testFileFullPath, filesChanged.Single());
|
||||
}
|
||||
});
|
||||
|
|
@ -93,18 +96,18 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void MoveFile(bool usePolling)
|
||||
public async Task MoveFile(bool usePolling)
|
||||
{
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
var srcFile = Path.Combine(dir, "foo");
|
||||
var dstFile = Path.Combine(dir, "foo2");
|
||||
|
||||
File.WriteAllText(srcFile, string.Empty);
|
||||
|
||||
using (var changedEv = new ManualResetEvent(false))
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var filesChanged = new HashSet<string>();
|
||||
|
||||
EventHandler<string> handler = null;
|
||||
|
|
@ -117,7 +120,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
watcher.EnableRaisingEvents = false;
|
||||
watcher.OnFileChange -= handler;
|
||||
|
||||
changedEv.Set();
|
||||
changedEv.TrySetResult(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -126,7 +129,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
|
||||
File.Move(srcFile, dstFile);
|
||||
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
await changedEv.Task.TimeoutAfter(DefaultTimeout);
|
||||
Assert.Contains(srcFile, filesChanged);
|
||||
Assert.Contains(dstFile, filesChanged);
|
||||
}
|
||||
|
|
@ -134,9 +137,9 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void FileInSubdirectory()
|
||||
public async Task FileInSubdirectory()
|
||||
{
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
var subdir = Path.Combine(dir, "subdir");
|
||||
Directory.CreateDirectory(subdir);
|
||||
|
|
@ -144,9 +147,9 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
var testFileFullPath = Path.Combine(subdir, "foo");
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
using (var changedEv = new ManualResetEvent(false))
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, true))
|
||||
{
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var filesChanged = new HashSet<string>();
|
||||
|
||||
EventHandler<string> handler = null;
|
||||
|
|
@ -158,7 +161,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
{
|
||||
watcher.EnableRaisingEvents = false;
|
||||
watcher.OnFileChange -= handler;
|
||||
changedEv.Set();
|
||||
changedEv.TrySetResult(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -168,10 +171,10 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
await Task.Delay(1000);
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
await changedEv.Task.TimeoutAfter(DefaultTimeout);
|
||||
Assert.Contains(subdir, filesChanged);
|
||||
Assert.Contains(testFileFullPath, filesChanged);
|
||||
}
|
||||
|
|
@ -181,14 +184,14 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void NoNotificationIfDisabled(bool usePolling)
|
||||
public async Task NoNotificationIfDisabled(bool usePolling)
|
||||
{
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
using (var changedEv = new ManualResetEvent(false))
|
||||
{
|
||||
watcher.OnFileChange += (_, f) => changedEv.Set();
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
watcher.OnFileChange += (_, f) => changedEv.TrySetResult(0);
|
||||
|
||||
// Disable
|
||||
watcher.EnableRaisingEvents = false;
|
||||
|
|
@ -198,10 +201,10 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
await Task.Delay(1000);
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
Assert.False(changedEv.WaitOne(DefaultTimeout / 2));
|
||||
await Assert.ThrowsAsync<TimeoutException>(() => changedEv.Task.TimeoutAfter(NegativeTimeout));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -209,37 +212,35 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void DisposedNoEvents(bool usePolling)
|
||||
public async Task DisposedNoEvents(bool usePolling)
|
||||
{
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
using (var changedEv = new ManualResetEvent(false))
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
watcher.OnFileChange += (_, f) => changedEv.Set();
|
||||
watcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
var testFileFullPath = Path.Combine(dir, "foo");
|
||||
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
Assert.False(changedEv.WaitOne(DefaultTimeout / 2));
|
||||
watcher.OnFileChange += (_, f) => changedEv.TrySetResult(0);
|
||||
watcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
var testFileFullPath = Path.Combine(dir, "foo");
|
||||
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
await Task.Delay(1000);
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
await Assert.ThrowsAsync<TimeoutException>(() => changedEv.Task.TimeoutAfter(NegativeTimeout));
|
||||
});
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void MultipleFiles(bool usePolling)
|
||||
public async Task MultipleFiles(bool usePolling)
|
||||
{
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
File.WriteAllText(Path.Combine(dir, "foo1"), string.Empty);
|
||||
File.WriteAllText(Path.Combine(dir, "foo2"), string.Empty);
|
||||
|
|
@ -249,9 +250,9 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
|
||||
var testFileFullPath = Path.Combine(dir, "foo3");
|
||||
|
||||
using (var changedEv = new ManualResetEvent(false))
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var filesChanged = new HashSet<string>();
|
||||
|
||||
EventHandler<string> handler = null;
|
||||
|
|
@ -260,7 +261,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
watcher.EnableRaisingEvents = false;
|
||||
watcher.OnFileChange -= handler;
|
||||
filesChanged.Add(f);
|
||||
changedEv.Set();
|
||||
changedEv.TrySetResult(0);
|
||||
};
|
||||
|
||||
watcher.OnFileChange += handler;
|
||||
|
|
@ -269,11 +270,11 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
await Task.Delay(1000);
|
||||
|
||||
File.WriteAllText(testFileFullPath, string.Empty);
|
||||
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
await changedEv.Task.TimeoutAfter(DefaultTimeout);
|
||||
Assert.Equal(testFileFullPath, filesChanged.Single());
|
||||
}
|
||||
});
|
||||
|
|
@ -282,11 +283,11 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void MultipleTriggers(bool usePolling)
|
||||
public async Task MultipleTriggers(bool usePolling)
|
||||
{
|
||||
var filesChanged = new HashSet<string>();
|
||||
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
|
|
@ -294,7 +295,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
AssertFileChangeRaisesEvent(dir, watcher);
|
||||
await AssertFileChangeRaisesEvent(dir, watcher);
|
||||
}
|
||||
|
||||
watcher.EnableRaisingEvents = false;
|
||||
|
|
@ -302,55 +303,53 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
});
|
||||
}
|
||||
|
||||
private void AssertFileChangeRaisesEvent(string directory, IFileSystemWatcher watcher)
|
||||
private async Task AssertFileChangeRaisesEvent(string directory, IFileSystemWatcher watcher)
|
||||
{
|
||||
using (var semaphoreSlim = new SemaphoreSlim(0))
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var expectedPath = Path.Combine(directory, Path.GetRandomFileName());
|
||||
EventHandler<string> handler = (object _, string f) =>
|
||||
{
|
||||
var expectedPath = Path.Combine(directory, Path.GetRandomFileName());
|
||||
EventHandler<string> handler = (object _, string f) =>
|
||||
{
|
||||
_output.WriteLine("File changed: " + f);
|
||||
try
|
||||
{
|
||||
if (string.Equals(f, expectedPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
semaphoreSlim.Release();
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// There's a known race condition here:
|
||||
// even though we tell the watcher to stop raising events and we unsubscribe the handler
|
||||
// there might be in-flight events that will still process. Since we dispose the reset
|
||||
// event, this code will fail if the handler executes after Dispose happens.
|
||||
}
|
||||
};
|
||||
|
||||
File.AppendAllText(expectedPath, " ");
|
||||
|
||||
watcher.OnFileChange += handler;
|
||||
_output.WriteLine("File changed: " + f);
|
||||
try
|
||||
{
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
Thread.Sleep(1000);
|
||||
File.AppendAllText(expectedPath, " ");
|
||||
Assert.True(semaphoreSlim.Wait(DefaultTimeout), "Expected a file change event for " + expectedPath);
|
||||
if (string.Equals(f, expectedPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
changedEv.TrySetResult(0);
|
||||
}
|
||||
}
|
||||
finally
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
watcher.OnFileChange -= handler;
|
||||
// There's a known race condition here:
|
||||
// even though we tell the watcher to stop raising events and we unsubscribe the handler
|
||||
// there might be in-flight events that will still process. Since we dispose the reset
|
||||
// event, this code will fail if the handler executes after Dispose happens.
|
||||
}
|
||||
};
|
||||
|
||||
File.AppendAllText(expectedPath, " ");
|
||||
|
||||
watcher.OnFileChange += handler;
|
||||
try
|
||||
{
|
||||
// On Unix the file write time is in 1s increments;
|
||||
// if we don't wait, there's a chance that the polling
|
||||
// watcher will not detect the change
|
||||
await Task.Delay(1000);
|
||||
File.AppendAllText(expectedPath, " ");
|
||||
await changedEv.Task.TimeoutAfter(DefaultTimeout);
|
||||
}
|
||||
finally
|
||||
{
|
||||
watcher.OnFileChange -= handler;
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void DeleteSubfolder(bool usePolling)
|
||||
public async Task DeleteSubfolder(bool usePolling)
|
||||
{
|
||||
UsingTempDirectory(dir =>
|
||||
await UsingTempDirectory(async dir =>
|
||||
{
|
||||
var subdir = Path.Combine(dir, "subdir");
|
||||
Directory.CreateDirectory(subdir);
|
||||
|
|
@ -363,9 +362,9 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
File.WriteAllText(f2, string.Empty);
|
||||
File.WriteAllText(f3, string.Empty);
|
||||
|
||||
using (var changedEv = new AutoResetEvent(false))
|
||||
using (var watcher = FileWatcherFactory.CreateWatcher(dir, usePolling))
|
||||
{
|
||||
var changedEv = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var filesChanged = new HashSet<string>();
|
||||
|
||||
EventHandler<string> handler = null;
|
||||
|
|
@ -377,7 +376,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
{
|
||||
watcher.EnableRaisingEvents = false;
|
||||
watcher.OnFileChange -= handler;
|
||||
changedEv.Set();
|
||||
changedEv.TrySetResult(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -386,7 +385,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
|
||||
Directory.Delete(subdir, recursive: true);
|
||||
|
||||
Assert.True(changedEv.WaitOne(DefaultTimeout));
|
||||
await changedEv.Task.TimeoutAfter(DefaultTimeout);
|
||||
|
||||
Assert.Contains(f1, filesChanged);
|
||||
Assert.Contains(f2, filesChanged);
|
||||
|
|
@ -396,7 +395,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
});
|
||||
}
|
||||
|
||||
private static void UsingTempDirectory(Action<string> action)
|
||||
private static async Task UsingTempDirectory(Func<string, Task> func)
|
||||
{
|
||||
var tempFolder = Path.Combine(Path.GetTempPath(), $"{nameof(FileWatcherTests)}-{Guid.NewGuid().ToString("N")}");
|
||||
if (Directory.Exists(tempFolder))
|
||||
|
|
@ -408,7 +407,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
|
||||
try
|
||||
{
|
||||
action(tempFolder);
|
||||
await func(tempFolder);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue