internal async Task GeneratedMethods_WithOutParams_DoNotCauseDeadlocks(string fixture)
{
var traceWriter = new TestTraceWriter(TraceLevel.Verbose);
ScriptHostConfiguration config = new ScriptHostConfiguration()
{
RootScriptPath = @"TestScripts\FunctionGeneration",
TraceWriter = traceWriter
};
string secretsPath = Path.Combine(Path.GetTempPath(), @"FunctionTests\Secrets");
WebHostSettings webHostSettings = new WebHostSettings();
var secretManager = new SecretManager(SettingsManager, secretsPath, NullTraceWriter.Instance);
using (var manager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), SettingsManager, webHostSettings))
{
Thread runLoopThread = new Thread(_ =>
{
manager.RunAndBlock(CancellationToken.None);
});
runLoopThread.IsBackground = true;
runLoopThread.Start();
await TestHelpers.Await(() =>
{
return manager.State == ScriptHostState.Running;
});
var request = new HttpRequestMessage(HttpMethod.Get, String.Format("http://localhost/api/httptrigger-{0}", fixture));
FunctionDescriptor function = manager.GetHttpFunctionOrNull(request);
SynchronizationContext currentContext = SynchronizationContext.Current;
var resetEvent = new ManualResetEventSlim();
try
{
var requestThread = new Thread(() =>
{
var context = new SingleThreadSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(context);
manager.HandleRequestAsync(function, request, CancellationToken.None)
.ContinueWith(task => resetEvent.Set());
Thread.Sleep(500);
context.Run();
});
requestThread.IsBackground = true;
requestThread.Start();
bool threadSignaled = resetEvent.Wait(TimeSpan.FromSeconds(10));
requestThread.Abort();
Assert.True(threadSignaled, "Thread execution did not complete");
}
finally
{
SynchronizationContext.SetSynchronizationContext(currentContext);
manager.Stop();
}
}
}