Cleanup some infrastructure pieces in Components

This commit is contained in:
Pranav K 2019-01-22 14:58:27 -08:00
parent ebb7f3ade3
commit c8319ece2a
No known key found for this signature in database
GPG Key ID: 1963DA6D96C3057A
5 changed files with 77 additions and 37 deletions

View File

@ -1,20 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.Internal;
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Threading;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure
{
class SeleniumStandaloneServer
{
private static object _instanceCreationLock = new object();
private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(30);
private static readonly object _instanceCreationLock = new object();
private static SeleniumStandaloneServer _instance;
public Uri Uri { get; }
@ -40,15 +43,30 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure
var port = FindAvailablePort();
Uri = new UriBuilder("http", "localhost", port, "/wd/hub").Uri;
var process = Process.Start(new ProcessStartInfo
var psi = new ProcessStartInfo
{
FileName = "npm",
Arguments = $"run selenium-standalone start -- -- -port {port}",
UseShellExecute = true,
});
RedirectStandardOutput = true,
RedirectStandardError = true,
};
PollUntilProcessStarted();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
psi.FileName = "cmd";
psi.Arguments = $"/c npm {psi.Arguments}";
}
var process = Process.Start(psi);
var builder = new StringBuilder();
process.OutputDataReceived += LogOutput;
process.ErrorDataReceived += LogOutput;
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// The Selenium sever has to be up for the entirety of the tests and is only shutdown when the application (i.e. the test) exits.
AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
{
if (!process.HasExited)
@ -57,34 +75,56 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure
process.Dispose();
}
};
}
private void PollUntilProcessStarted()
{
var timeoutAt = DateTime.Now.AddSeconds(30);
Exception lastException = null;
while (true)
void LogOutput(object sender, DataReceivedEventArgs e)
{
if (DateTime.Now > timeoutAt)
lock (builder)
{
throw new TimeoutException($"The selenium server instance did not start accepting requests at {Uri} before the timeout occurred. The last exception was: {lastException?.ToString() ?? "NULL"}");
builder.AppendLine(e.Data);
}
}
var waitForStart = Task.Run(async () =>
{
var httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(1),
};
while (true)
{
try
{
var responseTask = httpClient.GetAsync(Uri);
var response = await responseTask;
if (response.StatusCode == HttpStatusCode.OK)
{
break;
}
}
catch (OperationCanceledException)
{
}
await Task.Delay(1000);
}
});
try
{
waitForStart.TimeoutAfter(Timeout).Wait();
}
catch (Exception ex)
{
string output;
lock (builder)
{
output = builder.ToString();
}
var httpClient = new HttpClient();
try
{
var timeoutAfter1Second = new CancellationTokenSource(3000);
var response = httpClient.GetAsync(
Uri, timeoutAfter1Second.Token).Result;
response.EnsureSuccessStatusCode();
return;
}
catch (Exception ex)
{
lastException = ex;
}
Thread.Sleep(1000);
throw new InvalidOperationException($"Failed to start selenium sever. {Environment.NewLine}{output}", ex.GetBaseException());
}
}

View File

@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
public override void Dispose()
{
_serverToDispose.Dispose();
_serverToDispose?.Dispose();
}
}
}

View File

@ -1,5 +1,3 @@
/// <reference path="../../../../../src/microsoft.jsinterop/javascriptruntime/dist/microsoft.jsinterop.d.ts" />
// We'll store the results from the tests here
var results = {};
var assemblyName = 'BasicTestApp';

View File

@ -1,8 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<!-- Reference targets and props from Components.Build package -->
<Import Project="..\..\..\Build\src\ReferenceFromSource.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ReferenceBlazorBuildLocally>true</ReferenceBlazorBuildLocally>
</PropertyGroup>
<ItemGroup>

View File

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<!-- Reference targets and props from Components.Build package -->
<Import Project="..\..\..\Build\src\ReferenceFromSource.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<OutputType>library</OutputType>
<ReferenceBlazorBuildLocally>true</ReferenceBlazorBuildLocally>
</PropertyGroup>
<ItemGroup>
@ -22,6 +24,4 @@
<Reference Include="Microsoft.NET.Sdk.Razor" PrivateAssets="All" />
</ItemGroup>
<!-- In real content packages, use a <PackageReference> to Microsoft.AspNetCore.Blazor.Build instead. -->
</Project>