Fixed SmokeTestsOnNanoServer to provide dotent runtime to enable testing portable scenario
This commit is contained in:
parent
c14f37ac6a
commit
22175e03a7
|
|
@ -2,14 +2,42 @@
|
|||
{
|
||||
public class RemoteDeploymentConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Name or IP address of the server to deploy to
|
||||
/// </summary>
|
||||
public string ServerName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account name for the credentials required to setup a powershell session to the target server
|
||||
/// </summary>
|
||||
public string AccountName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account password for the credentials required to setup a powershell session to the target server
|
||||
/// </summary>
|
||||
public string AccountPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file share on the target server to copy the files to
|
||||
/// </summary>
|
||||
public string FileSharePath { get; set; }
|
||||
|
||||
public string ExecutableRelativePath { get; set; }
|
||||
/// <summary>
|
||||
/// Location of the dotnet runtime zip file which is required for testing portable apps.
|
||||
/// When both <see cref="DotnetRuntimeZipFilePath"/> and <see cref="DotnetRuntimeFolderPath"/> properties
|
||||
/// are provided, the <see cref="DotnetRuntimeZipFilePath"/> property is preferred.
|
||||
/// </summary>
|
||||
public string DotnetRuntimeZipFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Location of the dotnet runtime folder which is required for testing portable apps.
|
||||
/// This property is probably more useful for users as they can point their local 'dotnet' runtime folder.
|
||||
/// </summary>
|
||||
public string DotnetRuntimeFolderPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path to the parent folder containing 'dotnet.exe' on remote server's file share
|
||||
/// </summary>
|
||||
public string DotnetRuntimePathOnShare { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using E2ETests.Common;
|
||||
using Microsoft.AspNetCore.Server.Testing;
|
||||
|
|
@ -12,24 +13,55 @@ using Xunit.Abstractions;
|
|||
|
||||
namespace E2ETests
|
||||
{
|
||||
public class SmokeTestsOnNanoServer : IDisposable
|
||||
public class SmokeTestsOnNanoServerUsingStandaloneRuntime : IDisposable
|
||||
{
|
||||
private readonly SmokeTestsOnNanoServer _smokeTestsOnNanoServer;
|
||||
private readonly XunitLogger _logger;
|
||||
private readonly RemoteDeploymentConfig _remoteDeploymentConfig;
|
||||
|
||||
public SmokeTestsOnNanoServer(ITestOutputHelper output)
|
||||
public SmokeTestsOnNanoServerUsingStandaloneRuntime(ITestOutputHelper output)
|
||||
{
|
||||
_logger = new XunitLogger(output, LogLevel.Information);
|
||||
_remoteDeploymentConfig = RemoteDeploymentConfigHelper.GetConfiguration();
|
||||
_smokeTestsOnNanoServer = new SmokeTestsOnNanoServer(output, _remoteDeploymentConfig, _logger);
|
||||
}
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("remoteDeploymentConfig.json")
|
||||
.AddUserSecrets()
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
[ConditionalTheory, Trait("E2Etests", "NanoServer")]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[SkipIfEnvironmentVariableNotEnabled("RUN_TESTS_ON_NANO")]
|
||||
[InlineData(ServerType.Kestrel, 5000, ApplicationType.Standalone)]
|
||||
[InlineData(ServerType.WebListener, 5000, ApplicationType.Standalone)]
|
||||
public async Task Test(ServerType serverType, int portToListen, ApplicationType applicationType)
|
||||
{
|
||||
var applicationBaseUrl = $"http://{_remoteDeploymentConfig.ServerName}:{portToListen}/";
|
||||
await _smokeTestsOnNanoServer.RunTestsAsync(serverType, applicationBaseUrl, applicationType);
|
||||
}
|
||||
|
||||
_remoteDeploymentConfig = new RemoteDeploymentConfig();
|
||||
configuration.GetSection("NanoServer").Bind(_remoteDeploymentConfig);
|
||||
public void Dispose()
|
||||
{
|
||||
_logger.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// Tests here test portable app scenario, so we copy the dotnet runtime onto the
|
||||
// target server's file share and after setting up a remote session to the server, we update the PATH environment
|
||||
// to have the path to this copied dotnet runtime folder in the share.
|
||||
// The dotnet runtime is copied only once for all the tests in this class.
|
||||
public class SmokeTestsOnNanoServerUsingSharedRuntime
|
||||
: IClassFixture<SmokeTestsOnNanoServerUsingSharedRuntime.DotnetRuntimeSetupTestFixture>, IDisposable
|
||||
{
|
||||
private readonly SmokeTestsOnNanoServer _smokeTestsOnNanoServer;
|
||||
private readonly RemoteDeploymentConfig _remoteDeploymentConfig;
|
||||
private readonly XunitLogger _logger;
|
||||
|
||||
public SmokeTestsOnNanoServerUsingSharedRuntime(
|
||||
DotnetRuntimeSetupTestFixture dotnetRuntimeSetupTestFixture, ITestOutputHelper output)
|
||||
{
|
||||
_logger = new XunitLogger(output, LogLevel.Information);
|
||||
_remoteDeploymentConfig = RemoteDeploymentConfigHelper.GetConfiguration();
|
||||
_remoteDeploymentConfig.DotnetRuntimePathOnShare = dotnetRuntimeSetupTestFixture.DotnetRuntimePathOnShare;
|
||||
_smokeTestsOnNanoServer = new SmokeTestsOnNanoServer(output, _remoteDeploymentConfig, _logger);
|
||||
}
|
||||
|
||||
[ConditionalTheory, Trait("E2Etests", "NanoServer")]
|
||||
|
|
@ -37,21 +69,169 @@ namespace E2ETests
|
|||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[SkipIfEnvironmentVariableNotEnabled("RUN_TESTS_ON_NANO")]
|
||||
[InlineData(ServerType.Kestrel, 5000, ApplicationType.Portable)]
|
||||
[InlineData(ServerType.Kestrel, 5000, ApplicationType.Standalone)]
|
||||
[InlineData(ServerType.WebListener, 5000, ApplicationType.Portable)]
|
||||
[InlineData(ServerType.WebListener, 5000, ApplicationType.Standalone)]
|
||||
public async Task Test(ServerType serverType, int portToListen, ApplicationType applicationType)
|
||||
{
|
||||
var applicationBaseUrl = $"http://{_remoteDeploymentConfig.ServerName}:{portToListen}/";
|
||||
await RunTestsAsync(serverType, applicationBaseUrl, applicationType);
|
||||
await _smokeTestsOnNanoServer.RunTestsAsync(serverType, applicationBaseUrl, applicationType);
|
||||
}
|
||||
|
||||
private async Task RunTestsAsync(ServerType serverType, string applicationBaseUrl, ApplicationType applicationType)
|
||||
public void Dispose()
|
||||
{
|
||||
using (_logger.BeginScope("SmokeTestSuite"))
|
||||
_logger.Dispose();
|
||||
}
|
||||
|
||||
// Copies dotnet runtime to the target server's file share.
|
||||
public class DotnetRuntimeSetupTestFixture : IDisposable
|
||||
{
|
||||
public DotnetRuntimeSetupTestFixture()
|
||||
{
|
||||
RemoteDeploymentConfig = RemoteDeploymentConfigHelper.GetConfiguration();
|
||||
|
||||
DotnetRuntimePathOnShare = Path.Combine(RemoteDeploymentConfig.FileSharePath, "dotnet");
|
||||
|
||||
// Prefer copying the zip file to fileshare and extracting on file share over copying the extracted
|
||||
// dotnet runtime folder from source to file share as the size could be significantly huge.
|
||||
if (!string.IsNullOrEmpty(RemoteDeploymentConfig.DotnetRuntimeZipFilePath))
|
||||
{
|
||||
if (!File.Exists(RemoteDeploymentConfig.DotnetRuntimeZipFilePath))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Expected dotnet runtime zip file at '{RemoteDeploymentConfig.DotnetRuntimeFolderPath}', but didn't find one.");
|
||||
}
|
||||
|
||||
ZippedDotnetRuntimePathOnShare = Path.Combine(
|
||||
RemoteDeploymentConfig.FileSharePath,
|
||||
Path.GetFileName(RemoteDeploymentConfig.DotnetRuntimeZipFilePath));
|
||||
|
||||
if (!File.Exists(ZippedDotnetRuntimePathOnShare))
|
||||
{
|
||||
File.Copy(RemoteDeploymentConfig.DotnetRuntimeZipFilePath, ZippedDotnetRuntimePathOnShare, overwrite: true);
|
||||
Console.WriteLine($"Copied the local dotnet zip folder '{RemoteDeploymentConfig.DotnetRuntimeZipFilePath}' " +
|
||||
$"to the file share path '{RemoteDeploymentConfig.FileSharePath}'");
|
||||
}
|
||||
|
||||
if (Directory.Exists(DotnetRuntimePathOnShare))
|
||||
{
|
||||
Directory.Delete(DotnetRuntimePathOnShare, recursive: true);
|
||||
}
|
||||
|
||||
ZipFile.ExtractToDirectory(ZippedDotnetRuntimePathOnShare, DotnetRuntimePathOnShare);
|
||||
Console.WriteLine($"Extracted dotnet runtime to folder '{DotnetRuntimePathOnShare}'");
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(RemoteDeploymentConfig.DotnetRuntimeFolderPath))
|
||||
{
|
||||
if (!Directory.Exists(RemoteDeploymentConfig.DotnetRuntimeFolderPath))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Expected dotnet runtime folder at '{RemoteDeploymentConfig.DotnetRuntimeFolderPath}', but didn't find one.");
|
||||
}
|
||||
|
||||
Console.WriteLine($"Copying dotnet runtime folder from '{RemoteDeploymentConfig.DotnetRuntimeFolderPath}' to '{DotnetRuntimePathOnShare}'.");
|
||||
Console.WriteLine("This could take some time.");
|
||||
|
||||
DirectoryCopy(RemoteDeploymentConfig.DotnetRuntimeFolderPath, DotnetRuntimePathOnShare, copySubDirs: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Dotnet runtime is required to be copied for testing portable apps scenario. " +
|
||||
$"Either supply '{nameof(RemoteDeploymentConfig.DotnetRuntimeFolderPath)}' containing the unzipped dotnet runtime content or " +
|
||||
$"supply the dotnet runtime zip file path via '{nameof(RemoteDeploymentConfig.DotnetRuntimeZipFilePath)}'.");
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteDeploymentConfig RemoteDeploymentConfig { get; }
|
||||
|
||||
public string ZippedDotnetRuntimePathOnShare { get; }
|
||||
|
||||
public string DotnetRuntimePathOnShare { get; }
|
||||
|
||||
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
|
||||
{
|
||||
var dir = new DirectoryInfo(sourceDirName);
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException(
|
||||
"Source directory does not exist or could not be found: "
|
||||
+ sourceDirName);
|
||||
}
|
||||
|
||||
var dirs = dir.GetDirectories();
|
||||
if (!Directory.Exists(destDirName))
|
||||
{
|
||||
Directory.CreateDirectory(destDirName);
|
||||
}
|
||||
|
||||
var files = dir.GetFiles();
|
||||
foreach (var file in files)
|
||||
{
|
||||
var temppath = Path.Combine(destDirName, file.Name);
|
||||
file.CopyTo(temppath, false);
|
||||
}
|
||||
|
||||
if (copySubDirs)
|
||||
{
|
||||
foreach (var subdir in dirs)
|
||||
{
|
||||
var temppath = Path.Combine(destDirName, subdir.Name);
|
||||
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// In case the source is provided as a folder itself, then we wouldn't have the zip file to begin with.
|
||||
if (!string.IsNullOrEmpty(ZippedDotnetRuntimePathOnShare))
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Deleting the dotnet runtime zip file '{ZippedDotnetRuntimePathOnShare}'");
|
||||
File.Delete(ZippedDotnetRuntimePathOnShare);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to delete the dotnet runtime zip file '{ZippedDotnetRuntimePathOnShare}'. Exception: "
|
||||
+ ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Deleting the dotnet runtime folder '{DotnetRuntimePathOnShare}'");
|
||||
Directory.Delete(DotnetRuntimePathOnShare, recursive: true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to delete the dotnet runtime folder '{DotnetRuntimePathOnShare}'. Exception: "
|
||||
+ ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SmokeTestsOnNanoServer
|
||||
{
|
||||
private readonly XunitLogger _logger;
|
||||
private readonly RemoteDeploymentConfig _remoteDeploymentConfig;
|
||||
|
||||
public SmokeTestsOnNanoServer(ITestOutputHelper output, RemoteDeploymentConfig config, XunitLogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_remoteDeploymentConfig = config;
|
||||
}
|
||||
|
||||
public async Task RunTestsAsync(
|
||||
ServerType serverType,
|
||||
string applicationBaseUrl,
|
||||
ApplicationType applicationType)
|
||||
{
|
||||
using (_logger.BeginScope(nameof(SmokeTestsOnNanoServerUsingStandaloneRuntime)))
|
||||
{
|
||||
var deploymentParameters = new RemoteWindowsDeploymentParameters(
|
||||
Helpers.GetApplicationPath(applicationType),
|
||||
_remoteDeploymentConfig.DotnetRuntimePathOnShare,
|
||||
serverType,
|
||||
RuntimeFlavor.CoreClr,
|
||||
RuntimeArchitecture.x64,
|
||||
|
|
@ -75,10 +255,28 @@ namespace E2ETests
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
static class RemoteDeploymentConfigHelper
|
||||
{
|
||||
private static RemoteDeploymentConfig _remoteDeploymentConfig;
|
||||
|
||||
public static RemoteDeploymentConfig GetConfiguration()
|
||||
{
|
||||
_logger.Dispose();
|
||||
if (_remoteDeploymentConfig == null)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("remoteDeploymentConfig.json")
|
||||
.AddUserSecrets()
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
_remoteDeploymentConfig = new RemoteDeploymentConfig();
|
||||
configuration.GetSection("NanoServer").Bind(_remoteDeploymentConfig);
|
||||
}
|
||||
|
||||
return _remoteDeploymentConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
"AccountName": "",
|
||||
"AccountPassword": "",
|
||||
"FileSharePath": "",
|
||||
"ExecutableRelativePath": ""
|
||||
"DotnetRuntimeFolderPath": "",
|
||||
"DotnetRuntimeZipFilePath": ""
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue