зеркало из https://github.com/aspnet/MusicStore.git
Added smoke tests to verify on Nano server
This commit is contained in:
Родитель
10a1a15881
Коммит
40abffefcb
|
@ -25,7 +25,7 @@ namespace MusicStore
|
|||
{
|
||||
public class StartupSocialTesting
|
||||
{
|
||||
private readonly IRuntimeEnvironment _runtimeEnvironment;
|
||||
private readonly Platform _platform;
|
||||
|
||||
public StartupSocialTesting(IApplicationEnvironment appEnvironment, IRuntimeEnvironment runtimeEnvironment)
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ namespace MusicStore
|
|||
.AddJsonFile("configoverride.json", optional: true); // Used to override some configuration parameters that cannot be overridden by environment.
|
||||
|
||||
Configuration = builder.Build();
|
||||
_runtimeEnvironment = runtimeEnvironment;
|
||||
_platform = new Platform(runtimeEnvironment);
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; private set; }
|
||||
|
@ -48,7 +48,9 @@ namespace MusicStore
|
|||
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
|
||||
|
||||
//Sql client not available on mono
|
||||
var useInMemoryStore = !_runtimeEnvironment.OperatingSystem.Equals("Windows", StringComparison.OrdinalIgnoreCase);
|
||||
var useInMemoryStore = !_platform.IsRunningOnWindows
|
||||
|| _platform.IsRunningOnMono
|
||||
|| _platform.IsRunningOnNanoServer;
|
||||
|
||||
// Add EF services to the services container
|
||||
if (useInMemoryStore)
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
namespace E2ETests
|
||||
{
|
||||
public class RemoteDeploymentConfig
|
||||
{
|
||||
public string ServerName { get; set; }
|
||||
|
||||
public string AccountName { get; set; }
|
||||
|
||||
public string AccountPassword { get; set; }
|
||||
|
||||
public string FileSharePath { get; set; }
|
||||
|
||||
public string ExecutableRelativePath { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.Testing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace E2ETests
|
||||
{
|
||||
public static class SmokeTestHelper
|
||||
{
|
||||
public static async Task RunTestsAsync(DeploymentResult deploymentResult, ILogger logger)
|
||||
{
|
||||
var httpClientHandler = new HttpClientHandler();
|
||||
var httpClient = new HttpClient(httpClientHandler)
|
||||
{
|
||||
BaseAddress = new Uri(deploymentResult.ApplicationBaseUri),
|
||||
Timeout = TimeSpan.FromSeconds(5),
|
||||
};
|
||||
|
||||
using (httpClient)
|
||||
{
|
||||
// Request to base address and check if various parts of the body are rendered
|
||||
// & measure the cold startup time.
|
||||
var response = await RetryHelper.RetryRequest(async () =>
|
||||
{
|
||||
return await httpClient.GetAsync(string.Empty);
|
||||
}, logger, cancellationToken: deploymentResult.HostShutdownToken);
|
||||
|
||||
Assert.False(response == null, "Response object is null because the client could not " +
|
||||
"connect to the server after multiple retries");
|
||||
|
||||
var validator = new Validator(httpClient, httpClientHandler, logger, deploymentResult);
|
||||
|
||||
await validator.VerifyHomePage(response);
|
||||
|
||||
// Verify the static file middleware can serve static content.
|
||||
await validator.VerifyStaticContentServed();
|
||||
|
||||
// Making a request to a protected resource should automatically redirect to login page.
|
||||
await validator.AccessStoreWithoutPermissions();
|
||||
|
||||
// Register a user - Negative scenario where the Password & ConfirmPassword do not match.
|
||||
await validator.RegisterUserWithNonMatchingPasswords();
|
||||
|
||||
// Register a valid user.
|
||||
var generatedEmail = await validator.RegisterValidUser();
|
||||
|
||||
await validator.SignInWithUser(generatedEmail, "Password~1");
|
||||
|
||||
// Register a user - Negative scenario : Trying to register a user name that's already registered.
|
||||
await validator.RegisterExistingUser(generatedEmail);
|
||||
|
||||
// Logout from this user session - This should take back to the home page
|
||||
await validator.SignOutUser(generatedEmail);
|
||||
|
||||
// Sign in scenarios: Invalid password - Expected an invalid user name password error.
|
||||
await validator.SignInWithInvalidPassword(generatedEmail, "InvalidPassword~1");
|
||||
|
||||
// Sign in scenarios: Valid user name & password.
|
||||
await validator.SignInWithUser(generatedEmail, "Password~1");
|
||||
|
||||
// Change password scenario
|
||||
await validator.ChangePassword(generatedEmail);
|
||||
|
||||
// SignIn with old password and verify old password is not allowed and new password is allowed
|
||||
await validator.SignOutUser(generatedEmail);
|
||||
await validator.SignInWithInvalidPassword(generatedEmail, "Password~1");
|
||||
await validator.SignInWithUser(generatedEmail, "Password~2");
|
||||
|
||||
// Making a request to a protected resource that this user does not have access to - should
|
||||
// automatically redirect to the configured access denied page
|
||||
await validator.AccessStoreWithoutPermissions(generatedEmail);
|
||||
|
||||
// Logout from this user session - This should take back to the home page
|
||||
await validator.SignOutUser(generatedEmail);
|
||||
|
||||
// Login as an admin user
|
||||
await validator.SignInWithUser("Administrator@test.com", "YouShouldChangeThisPassword1!");
|
||||
|
||||
// Now navigating to the store manager should work fine as this user has
|
||||
// the necessary permission to administer the store.
|
||||
await validator.AccessStoreWithPermissions();
|
||||
|
||||
// Create an album
|
||||
var albumName = await validator.CreateAlbum();
|
||||
var albumId = await validator.FetchAlbumIdFromName(albumName);
|
||||
|
||||
// Get details of the album
|
||||
await validator.VerifyAlbumDetails(albumId, albumName);
|
||||
|
||||
// Verify status code pages acts on non-existing items.
|
||||
await validator.VerifyStatusCodePages();
|
||||
|
||||
// Get the non-admin view of the album.
|
||||
await validator.GetAlbumDetailsFromStore(albumId, albumName);
|
||||
|
||||
// Add an album to cart and checkout the same
|
||||
await validator.AddAlbumToCart(albumId, albumName);
|
||||
await validator.CheckOutCartItems();
|
||||
|
||||
// Delete the album from store
|
||||
await validator.DeleteAlbum(albumId, albumName);
|
||||
|
||||
// Logout from this user session - This should take back to the home page
|
||||
await validator.SignOutUser("Administrator");
|
||||
|
||||
// Google login
|
||||
await validator.LoginWithGoogle();
|
||||
|
||||
// Facebook login
|
||||
await validator.LoginWithFacebook();
|
||||
|
||||
// Twitter login
|
||||
await validator.LoginWithTwitter();
|
||||
|
||||
// MicrosoftAccountLogin
|
||||
await validator.LoginWithMicrosoftAccount();
|
||||
|
||||
logger.LogInformation("Variation completed successfully.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -122,7 +122,7 @@ namespace E2ETests
|
|||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[SkipIfCurrentRuntimeIsCoreClr]
|
||||
[SkipIfIISVariationsNotEnabled]
|
||||
[SkipIfEnvironmentVariableNotEnabled("IIS_VARIATIONS_ENABLED")]
|
||||
//[InlineData(ServerType.IIS, RuntimeFlavor.Clr, RuntimeArchitecture.x86, "http://localhost:5015/")]
|
||||
[InlineData(ServerType.IIS, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64, "http://localhost:5016/")]
|
||||
public async Task SmokeTestSuite_On_IIS_X86(
|
||||
|
@ -186,113 +186,10 @@ namespace E2ETests
|
|||
using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, _logger))
|
||||
{
|
||||
var deploymentResult = deployer.Deploy();
|
||||
|
||||
Helpers.SetInMemoryStoreForIIS(deploymentParameters, _logger);
|
||||
|
||||
var httpClientHandler = new HttpClientHandler();
|
||||
var httpClient = new HttpClient(httpClientHandler)
|
||||
{
|
||||
BaseAddress = new Uri(deploymentResult.ApplicationBaseUri),
|
||||
Timeout = TimeSpan.FromSeconds(5),
|
||||
};
|
||||
|
||||
// Request to base address and check if various parts of the body are rendered
|
||||
// & measure the cold startup time.
|
||||
var response = await RetryHelper.RetryRequest(async () =>
|
||||
{
|
||||
return await httpClient.GetAsync(string.Empty);
|
||||
}, logger: _logger, cancellationToken: deploymentResult.HostShutdownToken);
|
||||
|
||||
Assert.False(response == null, "Response object is null because the client could not " +
|
||||
"connect to the server after multiple retries");
|
||||
|
||||
var validator = new Validator(httpClient, httpClientHandler, _logger, deploymentResult);
|
||||
|
||||
await validator.VerifyHomePage(response);
|
||||
|
||||
// Verify the static file middleware can serve static content.
|
||||
await validator.VerifyStaticContentServed();
|
||||
|
||||
// Making a request to a protected resource should automatically redirect to login page.
|
||||
await validator.AccessStoreWithoutPermissions();
|
||||
|
||||
// Register a user - Negative scenario where the Password & ConfirmPassword do not match.
|
||||
await validator.RegisterUserWithNonMatchingPasswords();
|
||||
|
||||
// Register a valid user.
|
||||
var generatedEmail = await validator.RegisterValidUser();
|
||||
|
||||
await validator.SignInWithUser(generatedEmail, "Password~1");
|
||||
|
||||
// Register a user - Negative scenario : Trying to register a user name that's already registered.
|
||||
await validator.RegisterExistingUser(generatedEmail);
|
||||
|
||||
// Logout from this user session - This should take back to the home page
|
||||
await validator.SignOutUser(generatedEmail);
|
||||
|
||||
// Sign in scenarios: Invalid password - Expected an invalid user name password error.
|
||||
await validator.SignInWithInvalidPassword(generatedEmail, "InvalidPassword~1");
|
||||
|
||||
// Sign in scenarios: Valid user name & password.
|
||||
await validator.SignInWithUser(generatedEmail, "Password~1");
|
||||
|
||||
// Change password scenario
|
||||
await validator.ChangePassword(generatedEmail);
|
||||
|
||||
// SignIn with old password and verify old password is not allowed and new password is allowed
|
||||
await validator.SignOutUser(generatedEmail);
|
||||
await validator.SignInWithInvalidPassword(generatedEmail, "Password~1");
|
||||
await validator.SignInWithUser(generatedEmail, "Password~2");
|
||||
|
||||
// Making a request to a protected resource that this user does not have access to - should
|
||||
// automatically redirect to the configured access denied page
|
||||
await validator.AccessStoreWithoutPermissions(generatedEmail);
|
||||
|
||||
// Logout from this user session - This should take back to the home page
|
||||
await validator.SignOutUser(generatedEmail);
|
||||
|
||||
// Login as an admin user
|
||||
await validator.SignInWithUser("Administrator@test.com", "YouShouldChangeThisPassword1!");
|
||||
|
||||
// Now navigating to the store manager should work fine as this user has
|
||||
// the necessary permission to administer the store.
|
||||
await validator.AccessStoreWithPermissions();
|
||||
|
||||
// Create an album
|
||||
var albumName = await validator.CreateAlbum();
|
||||
var albumId = await validator.FetchAlbumIdFromName(albumName);
|
||||
|
||||
// Get details of the album
|
||||
await validator.VerifyAlbumDetails(albumId, albumName);
|
||||
|
||||
// Verify status code pages acts on non-existing items.
|
||||
await validator.VerifyStatusCodePages();
|
||||
|
||||
// Get the non-admin view of the album.
|
||||
await validator.GetAlbumDetailsFromStore(albumId, albumName);
|
||||
|
||||
// Add an album to cart and checkout the same
|
||||
await validator.AddAlbumToCart(albumId, albumName);
|
||||
await validator.CheckOutCartItems();
|
||||
|
||||
// Delete the album from store
|
||||
await validator.DeleteAlbum(albumId, albumName);
|
||||
|
||||
// Logout from this user session - This should take back to the home page
|
||||
await validator.SignOutUser("Administrator");
|
||||
|
||||
// Google login
|
||||
await validator.LoginWithGoogle();
|
||||
|
||||
// Facebook login
|
||||
await validator.LoginWithFacebook();
|
||||
|
||||
// Twitter login
|
||||
await validator.LoginWithTwitter();
|
||||
|
||||
// MicrosoftAccountLogin
|
||||
await validator.LoginWithMicrosoftAccount();
|
||||
|
||||
_logger.LogInformation("Variation completed successfully.");
|
||||
await SmokeTestHelper.RunTestsAsync(deploymentResult, _logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using E2ETests.Common;
|
||||
using Microsoft.AspNetCore.Server.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace E2ETests
|
||||
{
|
||||
public class SmokeTestsOnNanoServer : IDisposable
|
||||
{
|
||||
private readonly XunitLogger _logger;
|
||||
private readonly RemoteDeploymentConfig _remoteDeploymentConfig;
|
||||
|
||||
public SmokeTestsOnNanoServer(ITestOutputHelper output)
|
||||
{
|
||||
_logger = new XunitLogger(output, LogLevel.Information);
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("remoteDeploymentConfig.json")
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
|
||||
_remoteDeploymentConfig = new RemoteDeploymentConfig();
|
||||
configuration.GetSection("NanoServer").Bind(_remoteDeploymentConfig);
|
||||
}
|
||||
|
||||
[ConditionalTheory, Trait("E2Etests", "NanoServer")]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[SkipIfEnvironmentVariableNotEnabled("RUN_TESTS_ON_NANO")]
|
||||
[InlineData(ServerType.Kestrel, 5000)]
|
||||
[InlineData(ServerType.WebListener, 5000)]
|
||||
public async Task Test(ServerType serverType, int portToListen)
|
||||
{
|
||||
var applicationBaseUrl = $"http://{_remoteDeploymentConfig.ServerName}:{portToListen}/";
|
||||
await RunTestsAsync(serverType, applicationBaseUrl);
|
||||
}
|
||||
|
||||
private async Task RunTestsAsync(ServerType serverType, string applicationBaseUrl)
|
||||
{
|
||||
using (_logger.BeginScope("SmokeTestSuite"))
|
||||
{
|
||||
var deploymentParameters = new RemoteWindowsDeploymentParameters(
|
||||
Helpers.GetApplicationPath(),
|
||||
serverType,
|
||||
RuntimeFlavor.CoreClr,
|
||||
RuntimeArchitecture.x64,
|
||||
_remoteDeploymentConfig.FileSharePath,
|
||||
_remoteDeploymentConfig.ServerName,
|
||||
_remoteDeploymentConfig.AccountName,
|
||||
_remoteDeploymentConfig.AccountPassword,
|
||||
_remoteDeploymentConfig.ExecutableRelativePath)
|
||||
{
|
||||
PublishTargetFramework = "netstandardapp1.5",
|
||||
ApplicationBaseUriHint = applicationBaseUrl
|
||||
};
|
||||
deploymentParameters.EnvironmentVariables.Add(
|
||||
new KeyValuePair<string, string>("ASPNETCORE_ENVIRONMENT", "SocialTesting"));
|
||||
|
||||
using (var deployer = new RemoteWindowsDeployer(deploymentParameters, _logger))
|
||||
{
|
||||
var deploymentResult = deployer.Deploy();
|
||||
|
||||
await SmokeTestHelper.RunTestsAsync(deploymentResult, _logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_logger.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,9 @@
|
|||
"Microsoft.AspNetCore.Identity": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.Server.Testing": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.WebUtilities": "1.0.0-*",
|
||||
"Microsoft.Extensions.Configuration.Binder": "1.0.0-*",
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-*",
|
||||
"Microsoft.Extensions.Configuration.Json": "1.0.0-*",
|
||||
"Microsoft.Extensions.Logging": "1.0.0-*",
|
||||
"Microsoft.Extensions.Logging.Console": "1.0.0-*",
|
||||
"xunit": "2.1.0"
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"NanoServer": {
|
||||
"ServerName": "",
|
||||
"AccountName": "",
|
||||
"AccountPassword": "",
|
||||
"FileSharePath": "",
|
||||
"ExecutableRelativePath": ""
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче