[Templating][Fixes #15048] Fixes build hang in template tests caused by an unbound blocking collection (#15058)
This commit is contained in:
parent
49191f4d56
commit
cad6e06a83
|
|
@ -60,7 +60,7 @@ namespace Templates.Test.Helpers
|
||||||
Process = ProcessEx.Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), arguments, envVars: environmentVariables);
|
Process = ProcessEx.Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), arguments, envVars: environmentVariables);
|
||||||
if (hasListeningUri)
|
if (hasListeningUri)
|
||||||
{
|
{
|
||||||
ListeningUri = GetListeningUri(output);
|
ListeningUri = GetListeningUri(output) ?? throw new InvalidOperationException("Couldn't find the listening URL.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,16 +175,15 @@ namespace Templates.Test.Helpers
|
||||||
{
|
{
|
||||||
// Wait until the app is accepting HTTP requests
|
// Wait until the app is accepting HTTP requests
|
||||||
output.WriteLine("Waiting until ASP.NET application is accepting connections...");
|
output.WriteLine("Waiting until ASP.NET application is accepting connections...");
|
||||||
var listeningMessage = Process
|
var listeningMessage = GetListeningMessage();
|
||||||
.OutputLinesAsEnumerable
|
|
||||||
.Where(line => line != null)
|
|
||||||
.FirstOrDefault(line => line.Trim().StartsWith(ListeningMessagePrefix, StringComparison.Ordinal));
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(listeningMessage))
|
if (!string.IsNullOrEmpty(listeningMessage))
|
||||||
{
|
{
|
||||||
listeningMessage = listeningMessage.Trim();
|
listeningMessage = listeningMessage.Trim();
|
||||||
// Verify we have a valid URL to make requests to
|
// Verify we have a valid URL to make requests to
|
||||||
var listeningUrlString = listeningMessage.Substring(ListeningMessagePrefix.Length);
|
var listeningUrlString = listeningMessage.Substring(listeningMessage.IndexOf(
|
||||||
|
ListeningMessagePrefix, StringComparison.Ordinal) + ListeningMessagePrefix.Length);
|
||||||
|
|
||||||
output.WriteLine($"Detected that ASP.NET application is accepting connections on: {listeningUrlString}");
|
output.WriteLine($"Detected that ASP.NET application is accepting connections on: {listeningUrlString}");
|
||||||
listeningUrlString = listeningUrlString.Substring(0, listeningUrlString.IndexOf(':')) +
|
listeningUrlString = listeningUrlString.Substring(0, listeningUrlString.IndexOf(':')) +
|
||||||
"://localhost" +
|
"://localhost" +
|
||||||
|
|
@ -199,6 +198,25 @@ namespace Templates.Test.Helpers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetListeningMessage()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Process
|
||||||
|
// This will timeout at most after 5 minutes.
|
||||||
|
.OutputLinesAsEnumerable
|
||||||
|
.Where(line => line != null)
|
||||||
|
// This used to do StartsWith, but this is less strict and can prevent issues (very rare) where
|
||||||
|
// console logging interleaves with other console output in a bad way. For example:
|
||||||
|
// dbugNow listening on: http://127.0.0.1:12857
|
||||||
|
.FirstOrDefault(line => line.Trim().Contains(ListeningMessagePrefix, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsSuccessStatusCode(HttpResponseMessage response)
|
private bool IsSuccessStatusCode(HttpResponseMessage response)
|
||||||
{
|
{
|
||||||
return response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.Redirect;
|
return response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.Redirect;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Internal;
|
using Microsoft.Extensions.Internal;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
@ -26,6 +27,7 @@ namespace Templates.Test.Helpers
|
||||||
private readonly object _pipeCaptureLock = new object();
|
private readonly object _pipeCaptureLock = new object();
|
||||||
private BlockingCollection<string> _stdoutLines;
|
private BlockingCollection<string> _stdoutLines;
|
||||||
private TaskCompletionSource<int> _exited;
|
private TaskCompletionSource<int> _exited;
|
||||||
|
private CancellationTokenSource _stdoutLinesCancellationSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));
|
||||||
|
|
||||||
public ProcessEx(ITestOutputHelper output, Process proc)
|
public ProcessEx(ITestOutputHelper output, Process proc)
|
||||||
{
|
{
|
||||||
|
|
@ -71,7 +73,7 @@ namespace Templates.Test.Helpers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> OutputLinesAsEnumerable => _stdoutLines.GetConsumingEnumerable();
|
public IEnumerable<string> OutputLinesAsEnumerable => _stdoutLines.GetConsumingEnumerable(_stdoutLinesCancellationSource.Token);
|
||||||
|
|
||||||
public int ExitCode => _process.ExitCode;
|
public int ExitCode => _process.ExitCode;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue