public async Task InvalidProcessPath_ExpectServerError() { var dotnetLocation = "bogus"; using (StartLog(out var loggerFactory)) { var logger = loggerFactory.CreateLogger("HelloWorldTest"); var deploymentParameters = GetBaseDeploymentParameters(); // Point to dotnet installed in user profile. deploymentParameters.EnvironmentVariables["DotnetPath"] = Environment.ExpandEnvironmentVariables(dotnetLocation); // Path to dotnet. using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "processPath", "%DotnetPath%"); // Request to base address and check if various parts of the body are rendered & measure the cold startup time. var response = await RetryHelper.RetryRequest(() => { return(deploymentResult.HttpClient.GetAsync("HelloWorld")); }, logger, deploymentResult.HostShutdownToken, retryCount : 30); Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); } } }
public async Task CreateDefaultBuilderOfT_InitializeWithDefaults() { var applicationName = "CreateDefaultBuilderOfTApp"; await ExecuteTestApp(applicationName, async (deploymentResult, logger) => { var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), logger, deploymentResult.HostShutdownToken); var responseText = await response.Content.ReadAsStringAsync(); try { // Assert server is Kestrel Assert.Equal("Kestrel", response.Headers.Server.ToString()); // Set from default config Assert.Equal("http://localhost:5002/", deploymentResult.ApplicationBaseUri); // The application name will be sent in response when all asserts succeed in the test app. Assert.Equal(applicationName, responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } }, setTestEnvVars : true); }
public async Task NtlmAuthenticationTest(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, ApplicationType applicationType, string applicationBaseUrl) { using (_logger.BeginScope("NtlmAuthenticationTest")) { var musicStoreDbName = DbUtils.GetUniqueName(); var deploymentParameters = new DeploymentParameters(Helpers.GetApplicationPath(applicationType), serverType, runtimeFlavor, architecture) { PublishApplicationBeforeDeployment = true, TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net451" : "netcoreapp1.0", ApplicationType = applicationType, ApplicationBaseUriHint = applicationBaseUrl, EnvironmentName = "NtlmAuthentication", //Will pick the Start class named 'StartupNtlmAuthentication' ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("NtlmAuthentation.config") : null, SiteName = "MusicStoreNtlmAuthentication", //This is configured in the NtlmAuthentication.config UserAdditionalCleanup = parameters => { DbUtils.DropDatabase(musicStoreDbName, _logger); } }; // Override the connection strings using environment based configuration deploymentParameters.EnvironmentVariables .Add(new KeyValuePair <string, string>( MusicStore.StoreConfig.ConnectionStringKey, DbUtils.CreateConnectionString(musicStoreDbName))); using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, _logger)) { var deploymentResult = deployer.Deploy(); var httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) }; // 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); Console.WriteLine("Verifying home page"); await validator.VerifyNtlmHomePage(response); Console.WriteLine("Verifying access to store with permissions"); await validator.AccessStoreWithPermissions(); _logger.LogInformation("Variation completed successfully."); } } }
private async Task RunSite(ServerType server, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl) { await TestServices.RunSiteTest( SiteName, server, runtimeFlavor, architecture, applicationBaseUrl, async (httpClient, logger, token) => { // ===== English ===== var response = await RetryHelper.RetryRequest(async() => { return(await httpClient.GetAsync(string.Empty)); }, logger, token, retryCount: 30); var responseText = await response.Content.ReadAsStringAsync(); var headingIndex = responseText.IndexOf("<h2>Application uses</h2>"); Assert.True(headingIndex >= 0); // ===== French ===== response = await RetryHelper.RetryRequest(async() => { return(await httpClient.GetAsync("?culture=fr&ui-culture=fr")); }, logger, token, retryCount: 30); responseText = await response.Content.ReadAsStringAsync(); headingIndex = responseText.IndexOf("<h2>Utilisations d'application</h2>"); Assert.True(headingIndex >= 0); }); }
private async Task RunSite(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl) { await TestServices.RunSiteTest( SiteName, serverType, runtimeFlavor, architecture, applicationBaseUrl, async (httpClient, logger, token) => { var response = await RetryHelper.RetryRequest(async() => { return(await httpClient.GetAsync(string.Empty)); }, logger, token, retryCount: 30); var responseText = await response.Content.ReadAsStringAsync(); string expectedText = "Retry Count 42\r\n" + "Default Ad Block House\r\n" + "Ad Block Contoso Origin sql-789 Product Code contoso2014\r\n" + "Ad Block House Origin blob-456 Product Code 123\r\n"; logger.LogResponseOnFailedAssert(response, responseText, () => { Assert.Equal(expectedText, responseText); }); }); }
public async Task RunsInIISExpressInProcess() { var applicationName = "CreateDefaultBuilderApp"; var deploymentParameters = new DeploymentParameters(Path.Combine(GetTestSitesPath(), applicationName), ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { TargetFramework = "netcoreapp2.2", HostingModel = HostingModel.InProcess, AncmVersion = AncmVersion.AspNetCoreModuleV2 }; SetEnvironmentVariables(deploymentParameters, "Development"); using (var deployer = IISApplicationDeployerFactory.Create(deploymentParameters, LoggerFactory)) { var deploymentResult = await deployer.DeployAsync(); var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), Logger, deploymentResult.HostShutdownToken, retryCount : 5); var responseText = await response.Content.ReadAsStringAsync(); try { // Assert server is IISExpress Assert.Equal("Microsoft-IIS/10.0", response.Headers.Server.ToString()); // The application name will be sent in response when all asserts succeed in the test app. Assert.Equal(applicationName, responseText); } catch (XunitException) { Logger.LogWarning(response.ToString()); Logger.LogWarning(responseText); throw; } } }
[Fact] // Consistently fails on CI for net461 public async Task StandaloneApplication_ExpectCorrectPublish() { using (StartLog(out var loggerFactory)) { var logger = loggerFactory.CreateLogger("HelloWorldTest"); var deploymentParameters = GetBaseDeploymentParameters(); using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); deploymentParameters.ApplicationType = ApplicationType.Standalone; // Request to base address and check if various parts of the body are rendered & measure the cold startup time. var response = await RetryHelper.RetryRequest(() => { return(deploymentResult.HttpClient.GetAsync("HelloWorld")); }, logger, deploymentResult.HostShutdownToken, retryCount : 30); var responseText = await response.Content.ReadAsStringAsync(); try { Assert.Equal("Hello World", responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } } } }
private async Task OpenIdConnectTestSuite(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl) { var logger = new LoggerFactory() .AddConsole(LogLevel.Warning) .CreateLogger(string.Format("OpenId:{0}:{1}:{2}", serverType, runtimeFlavor, architecture)); using (logger.BeginScope("OpenIdConnectTestSuite")) { var musicStoreDbName = Guid.NewGuid().ToString().Replace("-", string.Empty); var connectionString = string.Format(DbUtils.CONNECTION_STRING_FORMAT, musicStoreDbName); var deploymentParameters = new DeploymentParameters(Helpers.GetApplicationPath(), serverType, runtimeFlavor, architecture) { ApplicationBaseUriHint = applicationBaseUrl, EnvironmentName = "OpenIdConnectTesting", UserAdditionalCleanup = parameters => { if (!Helpers.RunningOnMono) { // Mono uses InMemoryStore DbUtils.DropDatabase(musicStoreDbName, logger); } } }; // Override the connection strings using environment based configuration deploymentParameters.EnvironmentVariables .Add(new KeyValuePair <string, string>( "SQLAZURECONNSTR_DefaultConnection", string.Format(DbUtils.CONNECTION_STRING_FORMAT, musicStoreDbName))); using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger)) { var deploymentResult = deployer.Deploy(); var httpClientHandler = new HttpClientHandler(); var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) }; // 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); // OpenIdConnect login. await validator.LoginWithOpenIdConnect(); logger.LogInformation("Variation completed successfully."); } } }
private async Task OpenIdConnectTestSuite(ServerType serverType, RuntimeFlavor runtimeFlavor, ApplicationType applicationType) { var architecture = RuntimeArchitecture.x64; var testName = $"OpenIdConnectTestSuite_{serverType}_{runtimeFlavor}_{architecture}_{applicationType}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger("OpenIdConnectTestSuite"); var musicStoreDbName = DbUtils.GetUniqueName(); var deploymentParameters = new DeploymentParameters(Helpers.GetApplicationPath(applicationType), serverType, runtimeFlavor, architecture) { PublishApplicationBeforeDeployment = true, PreservePublishedApplicationForDebugging = Helpers.PreservePublishedApplicationForDebugging, TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0", Configuration = Helpers.GetCurrentBuildConfiguration(), ApplicationType = applicationType, EnvironmentName = "OpenIdConnectTesting", UserAdditionalCleanup = parameters => { DbUtils.DropDatabase(musicStoreDbName, logger); }, AdditionalPublishParameters = " /p:PublishForTesting=true" }; // Override the connection strings using environment based configuration deploymentParameters.EnvironmentVariables .Add(new KeyValuePair <string, string>( MusicStoreConfig.ConnectionStringKey, DbUtils.CreateConnectionString(musicStoreDbName))); using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); var httpClientHandler = new HttpClientHandler(); var httpClient = deploymentResult.CreateHttpClient(httpClientHandler); // 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); logger.LogInformation("Verifying home page"); await validator.VerifyHomePage(response); logger.LogInformation("Verifying login by OpenIdConnect"); await validator.LoginWithOpenIdConnect(); logger.LogInformation("Variation completed successfully."); } } }
private async Task HelloWorld(RuntimeFlavor runtimeFlavor, ApplicationType applicationType) { var serverType = ServerType.IISExpress; var architecture = RuntimeArchitecture.x64; var testName = $"HelloWorld_{runtimeFlavor}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger("HelloWorldTest"); var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(), serverType, runtimeFlavor, architecture) { EnvironmentName = "HelloWorld", // Will pick the Start class named 'StartupHelloWorld', ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("Http.config") : null, SiteName = "HttpTestSite", // This is configured in the Http.config TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0", ApplicationType = applicationType }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); deploymentResult.HttpClient.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(() => { return(deploymentResult.HttpClient.GetAsync(string.Empty)); }, logger, deploymentResult.HostShutdownToken, retryCount : 30); var responseText = await response.Content.ReadAsStringAsync(); try { Assert.Equal("Hello World", responseText); response = await deploymentResult.HttpClient.GetAsync("/Path%3F%3F?query"); responseText = await response.Content.ReadAsStringAsync(); Assert.Equal("/Path??", responseText); response = await deploymentResult.HttpClient.GetAsync("/Query%3FPath?query?"); responseText = await response.Content.ReadAsStringAsync(); Assert.Equal("?query?", responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } } } }
private async Task ResponseCompression(TestVariant variant, Func <HttpClient, ILogger, Task> scenario, bool hostCompression, [CallerMemberName] string testName = null) { testName = $"{testName}_{variant.Server}_{variant.Tfm}_{variant.Architecture}_{variant.ApplicationType}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger("ResponseCompression"); var deploymentParameters = new DeploymentParameters(variant) { ApplicationPath = Helpers.GetApplicationPath(), EnvironmentName = "ResponseCompression", }; if (hostCompression) { deploymentParameters.ServerConfigTemplateContent = Helpers.GetNginxConfigContent(variant.Server, "nginx.conf"); } else { deploymentParameters.ServerConfigTemplateContent = Helpers.GetConfigContent(variant.Server, "NoCompression.config", "NoCompression.conf"); } using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); var httpClientHandler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.None }; Assert.True(httpClientHandler.SupportsAutomaticDecompression); var httpClient = deploymentResult.CreateHttpClient(httpClientHandler); // Request to base address and check if various parts of the body are rendered & measure the cold startup time. var response = await RetryHelper.RetryRequest(() => { return(httpClient.GetAsync(string.Empty)); }, logger, deploymentResult.HostShutdownToken); var responseText = await response.Content.ReadAsStringAsync(); try { Assert.Equal("Running", responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } await scenario(httpClient, logger); } } }
private async Task HttpsHelloWorld(RuntimeFlavor runtimeFlavor, ApplicationType applicationType, int port) { var serverType = ServerType.IISExpress; var architecture = RuntimeArchitecture.x64; var applicationBaseUrl = $"https://localhost:{port}/"; var testName = $"HttpsHelloWorld_{runtimeFlavor}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger("HttpsHelloWorldTest"); var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(), serverType, runtimeFlavor, architecture) { ApplicationBaseUriHint = applicationBaseUrl, EnvironmentName = "HttpsHelloWorld", // Will pick the Start class named 'StartupHttpsHelloWorld', ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("Https.config") : null, SiteName = "HttpsTestSite", // This is configured in the Https.config TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0", ApplicationType = applicationType, Configuration = #if DEBUG "Debug" #else "Release" #endif }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); var handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = (a, b, c, d) => true; var httpClient = deploymentResult.CreateHttpClient(handler); httpClient.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(() => { return(httpClient.GetAsync(string.Empty)); }, logger, deploymentResult.HostShutdownToken, retryCount : 30); var responseText = await response.Content.ReadAsStringAsync(); try { Assert.Equal("Scheme:https; Original:http", responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } } } }
protected override async Task ValidateAsync(HttpClient httpClient, ILogger logger, CancellationToken token) { // calltwo and callthree in the expression below // increment on every call. // The test verifies that everything else stays the same // and that the two values that change are increasing in value var responseMatcher = @"---------- MyMiddleware ctor\r\n" + @"CallOne\[1\]\r\n" + @"CallTwo\[2\]\r\n" + @"CallThree\[3\]\r\n" + @"---------- context\.RequestServices\r\n" + @"CallOne\[1\]\r\n" + @"CallTwo\[(?<calltwo>\d+)\]\r\n" + @"CallThree\[(?<callthree>\d+)\]\r\n" + @"---------- Done\r\n"; var responseRegex = new Regex(responseMatcher, RegexOptions.Compiled | RegexOptions.Multiline); // ===== First call ===== logger.LogInformation("First call"); var response = await RetryHelper.RetryRequest(async() => { return(await httpClient.GetAsync(string.Empty)); }, logger, token, retryCount : 30); var responseText = await response.Content.ReadAsStringAsync(); var match = responseRegex.Match(responseText); Assert.True(match.Success); var callTwo1 = int.Parse(match.Groups["calltwo"].Value); var callThree1 = int.Parse(match.Groups["callthree"].Value); // ===== Second call ===== logger.LogInformation("Second call"); response = await RetryHelper.RetryRequest(async() => { return(await httpClient.GetAsync(string.Empty)); }, logger, token, retryCount : 30); responseText = await response.Content.ReadAsStringAsync(); logger.LogResponseOnFailedAssert(response, responseText, () => { match = responseRegex.Match(responseText); Assert.True(match.Success); var callTwo2 = int.Parse(match.Groups["calltwo"].Value); var callThree2 = int.Parse(match.Groups["callthree"].Value); Assert.True(callTwo1 < callTwo2); Assert.True(callThree1 < callThree2); }); }
private async Task <HttpResponseMessage> GetFromCDN(string src) { var logger = NullLogger.Instance; return(await RetryHelper.RetryRequest(async() => { var request = new HttpRequestMessage(HttpMethod.Get, new Uri(src)); return await _httpClient.SendAsync(request); }, logger)); }
private async Task UpgradeFeatureDetectionDeployer(RuntimeFlavor runtimeFlavor, ApplicationType applicationType, string configPath, string sitePath, string expected) { var serverType = ServerType.IISExpress; var architecture = RuntimeArchitecture.x64; var testName = $"HelloWorld_{runtimeFlavor}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger("HelloWorldTest"); var deploymentParameters = new DeploymentParameters(Helpers.GetInProcessTestSitesPath(), serverType, runtimeFlavor, architecture) { EnvironmentName = "UpgradeFeatureDetection", // Will pick the Start class named 'StartupHelloWorld', ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText(configPath) : null, SiteName = "HttpTestSite", // This is configured in the Http.config TargetFramework = "netcoreapp2.1", ApplicationType = applicationType, Configuration = #if DEBUG "Debug" #else "Release" #endif }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); deploymentResult.HttpClient.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(() => { return(deploymentResult.HttpClient.GetAsync("UpgradeFeatureDetection")); }, logger, deploymentResult.HostShutdownToken, retryCount : 30); var responseText = await response.Content.ReadAsStringAsync(); try { Assert.Equal(expected, responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } } } } }
public async Task DeployTestAndAddToSpec(ServerType server, bool ssl, string environment, CancellationToken cancellationToken, Action <AutobahnExpectations> expectationConfig = null) { var sslNamePart = ssl ? "SSL" : "NoSSL"; var name = $"{server}|{sslNamePart}|{environment}"; var logger = _loggerFactory.CreateLogger($"AutobahnTestApp:{server}:{sslNamePart}:{environment}"); var appPath = Helpers.GetApplicationPath("AutobahnTestApp"); var configPath = Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "Http.config"); var parameters = new DeploymentParameters(appPath, server, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { Scheme = (ssl ? Uri.UriSchemeHttps : Uri.UriSchemeHttp), ApplicationType = ApplicationType.Portable, TargetFramework = "Net5.0", EnvironmentName = environment, SiteName = "HttpTestSite", // This is configured in the Http.config ServerConfigTemplateContent = (server == ServerType.IISExpress) ? File.ReadAllText(configPath) : null, }; var deployer = ApplicationDeployerFactory.Create(parameters, _loggerFactory); var result = await deployer.DeployAsync(); _deployers.Add(deployer); _deployments.Add(result); cancellationToken.ThrowIfCancellationRequested(); var handler = new HttpClientHandler(); // Win7 HttpClient on NetCoreApp2.2 defaults to TLS 1.0 and won't connect to Kestrel. https://github.com/dotnet/corefx/issues/28733 // Mac HttpClient on NetCoreApp2.0 doesn't alow you to set some combinations. // https://github.com/dotnet/corefx/blob/586cffcdfdf23ad6c193a4bf37fce88a1bf69508/src/System.Net.Http/src/System/Net/Http/CurlHandler/CurlHandler.SslProvider.OSX.cs#L104-L106 handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; var client = result.CreateHttpClient(handler); // Make sure the server works var resp = await RetryHelper.RetryRequest(() => { cancellationToken.ThrowIfCancellationRequested(); return(client.GetAsync(result.ApplicationBaseUri)); }, logger, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, result.HostShutdownToken).Token); resp.EnsureSuccessStatusCode(); cancellationToken.ThrowIfCancellationRequested(); // Add to the current spec var wsUrl = result.ApplicationBaseUri.Replace("https://", "wss://").Replace("http://", "ws://"); Spec.WithServer(name, wsUrl); var expectations = new AutobahnExpectations(server, ssl, environment); expectationConfig?.Invoke(expectations); _expectations.Add(expectations); cancellationToken.ThrowIfCancellationRequested(); }
public async Task RunDeveloperTests( ServerType serverType, RuntimeFlavor runtimeFlavor, ApplicationType applicationType, RuntimeArchitecture runtimeArchitecture) { var testName = $"PublishAndRunTests_{serverType}_{runtimeFlavor}_{applicationType}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger("Publish_And_Run_Development"); var musicStoreDbName = DbUtils.GetUniqueName(); var deploymentParameters = new DeploymentParameters( Helpers.GetApplicationPath(applicationType), serverType, runtimeFlavor, runtimeArchitecture) { PublishApplicationBeforeDeployment = true, PreservePublishedApplicationForDebugging = Helpers.PreservePublishedApplicationForDebugging, TargetFramework = Helpers.GetTargetFramework(runtimeFlavor), Configuration = Helpers.GetCurrentBuildConfiguration(), EnvironmentName = "Development", ApplicationType = applicationType, UserAdditionalCleanup = parameters => { DbUtils.DropDatabase(musicStoreDbName, logger); } }; // Override the connection strings using environment based configuration deploymentParameters.EnvironmentVariables .Add(new KeyValuePair <string, string>( MusicStoreConfig.ConnectionStringKey, DbUtils.CreateConnectionString(musicStoreDbName))); using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); var httpClientHandler = new HttpClientHandler { UseDefaultCredentials = true }; var httpClient = deploymentResult.CreateHttpClient(httpClientHandler); // Request to base address and check if various parts of the body are rendered & // measure the cold startup time. // Add retry logic since tests are flaky on mono due to connection issues var validator = new Validator(httpClient, httpClientHandler, logger, deploymentResult); var response = await RetryHelper.RetryRequest(() => httpClient.GetAsync("PageThatThrows"), logger, cancellationToken : deploymentResult.HostShutdownToken); logger.LogInformation("Verifying developer exception page"); await validator.VerifyDeveloperExceptionPage(response); logger.LogInformation("Variation completed successfully."); } } }
public async Task DotnetRun_Tests(TestVariant variant) { var testName = $"DotnetRunTests_{variant}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger("DotnetRunTests"); var musicStoreDbName = DbUtils.GetUniqueName(); var deploymentParameters = new DeploymentParameters(variant) { ApplicationPath = Helpers.GetApplicationPath(), PublishApplicationBeforeDeployment = false, EnvironmentName = "Development", UserAdditionalCleanup = parameters => { DbUtils.DropDatabase(musicStoreDbName, logger); }, EnvironmentVariables = { { MusicStoreConfig.ConnectionStringKey, DbUtils.CreateConnectionString(musicStoreDbName) }, }, }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); var httpClientHandler = new HttpClientHandler { UseDefaultCredentials = true }; var httpClient = deploymentResult.CreateHttpClient(httpClientHandler); var response = await RetryHelper.RetryRequest( () => httpClient.GetAsync(string.Empty), logger, 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); logger.LogInformation("Verifying home page"); // Verify HomePage should validate that we're using precompiled views. await validator.VerifyHomePage(response); // Verify developer exception page logger.LogInformation("Verifying developer exception page"); response = await RetryHelper.RetryRequest( () => httpClient.GetAsync("PageThatThrows"), logger, cancellationToken : deploymentResult.HostShutdownToken); await validator.VerifyDeveloperExceptionPage(response); logger.LogInformation("Variation completed successfully."); } } }
public async Task DeployTestAndAddToSpec(ServerType server, bool ssl, Action <AutobahnExpectations> expectationConfig = null) { var port = Interlocked.Increment(ref _nextPort); var baseUrl = ssl ? $"https://localhost:{port}" : $"http://localhost:{port}"; var sslNamePart = ssl ? "SSL" : "NoSSL"; var name = $"{server}|{sslNamePart}"; var logger = _loggerFactory.CreateLogger($"AutobahnTestApp:{server}:{sslNamePart}"); var appPath = Helpers.GetApplicationPath("WebSocketsTestApp"); var parameters = new DeploymentParameters(appPath, server, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { ApplicationBaseUriHint = baseUrl, ApplicationType = ApplicationType.Portable, TargetFramework = "netcoreapp1.1", EnvironmentName = "Development" }; var deployer = ApplicationDeployerFactory.Create(parameters, logger); var result = deployer.Deploy(); result.HostShutdownToken.ThrowIfCancellationRequested(); #if NET451 System.Net.ServicePointManager.ServerCertificateValidationCallback = (_, __, ___, ____) => true; var client = new HttpClient(); #else var handler = new HttpClientHandler(); if (ssl) { // Don't take this out of the "if(ssl)". If we set it on some platforms, it crashes // So we avoid running SSL tests on those platforms (for now). // See https://github.com/dotnet/corefx/issues/9728 handler.ServerCertificateCustomValidationCallback = (_, __, ___, ____) => true; } var client = new HttpClient(handler); #endif // Make sure the server works var resp = await RetryHelper.RetryRequest(() => { return(client.GetAsync(result.ApplicationBaseUri)); }, logger, result.HostShutdownToken, retryCount : 5); resp.EnsureSuccessStatusCode(); // Add to the current spec var wsUrl = result.ApplicationBaseUri.Replace("https://", "wss://").Replace("http://", "ws://"); Spec.WithServer(name, wsUrl); _deployers.Add(deployer); var expectations = new AutobahnExpectations(server, ssl); expectationConfig?.Invoke(expectations); _expectations.Add(expectations); }
// TODO: temporarily disabling x86 tests as dotnet xunit test runner currently does not support 32-bit //[ConditionalTheory(Skip = "https://github.com/aspnet/MusicStore/issues/565"), Trait("E2Etests", "E2Etests")] //[OSSkipCondition(OperatingSystems.Windows)] //[InlineData(ServerType.Kestrel, RuntimeFlavor.Clr, RuntimeArchitecture.x86, ApplicationType.Portable, "http://localhost:5045/")] //public async Task OpenIdConnect_OnMono(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, ApplicationType applicationType, string applicationBaseUrl) //{ // await OpenIdConnectTestSuite(serverType, runtimeFlavor, architecture, applicationBaseUrl); //} private async Task OpenIdConnectTestSuite(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, ApplicationType applicationType, string applicationBaseUrl) { using (_logger.BeginScope("OpenIdConnectTestSuite")) { var musicStoreDbName = DbUtils.GetUniqueName(); var deploymentParameters = new DeploymentParameters(Helpers.GetApplicationPath(applicationType), serverType, runtimeFlavor, architecture) { PublishApplicationBeforeDeployment = true, PublishTargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net451" : "netcoreapp1.0", ApplicationType = applicationType, ApplicationBaseUriHint = applicationBaseUrl, EnvironmentName = "OpenIdConnectTesting", UserAdditionalCleanup = parameters => { DbUtils.DropDatabase(musicStoreDbName, _logger); } }; // Override the connection strings using environment based configuration deploymentParameters.EnvironmentVariables .Add(new KeyValuePair <string, string>( MusicStore.StoreConfig.ConnectionStringKey, DbUtils.CreateConnectionString(musicStoreDbName))); using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, _logger)) { var deploymentResult = deployer.Deploy(); var httpClientHandler = new HttpClientHandler(); var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) }; // 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); Console.WriteLine("Verifying home page"); await validator.VerifyHomePage(response); Console.WriteLine("Verifying login by OpenIdConnect"); await validator.LoginWithOpenIdConnect(); _logger.LogInformation("Variation completed successfully."); } } }
private async Task JavaScriptSnippetInjectionTestSuite(string targetFramework, ApplicationType applicationType) { var testName = $"ApplicationInsightsJavaScriptSnippetTest_{applicationType}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger(nameof(JavaScriptSnippetTest)); var deploymentParameters = new DeploymentParameters(GetApplicationPath(), ServerType.Kestrel, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { PublishApplicationBeforeDeployment = true, PreservePublishedApplicationForDebugging = PreservePublishedApplicationForDebugging, TargetFramework = targetFramework, Configuration = GetCurrentBuildConfiguration(), ApplicationType = applicationType, EnvironmentName = "JavaScript", EnvironmentVariables = { new KeyValuePair <string, string>( "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", "Microsoft.AspNetCore.ApplicationInsights.HostingStartup"), }, }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); var httpClientHandler = new HttpClientHandler(); var httpClient = deploymentResult.CreateHttpClient(httpClientHandler); // 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("/Home/ScriptCheck")); }, 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); logger.LogInformation("Verifying layout page"); await validator.VerifyLayoutPage(response); logger.LogInformation("Verifying layout page before script"); await validator.VerifyLayoutPageBeforeScript(response); logger.LogInformation("Verifying layout page after script"); await validator.VerifyLayoutPageAfterScript(response); logger.LogInformation("Variation completed successfully."); } } }
public async Task ContainsLinks(Page page) { var response = await RetryHelper.RetryRequest(async() => { var request = new HttpRequestMessage( HttpMethod.Get, new Uri(ListeningUri, page.Url)); return(await _httpClient.SendAsync(request)); }, logger : NullLogger.Instance); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var parser = new HtmlParser(); var html = await parser.ParseAsync(await response.Content.ReadAsStreamAsync()); foreach (IHtmlLinkElement styleSheet in html.GetElementsByTagName("link")) { Assert.Equal("stylesheet", styleSheet.Relation); // Workaround for https://github.com/dotnet/aspnetcore/issues/31030#issuecomment-811334450 // Cleans up incorrectly generated filename for scoped CSS files var styleSheetHref = styleSheet.Href.Replace("_", string.Empty).Replace("about://", string.Empty); await AssertOk(styleSheetHref); } foreach (var script in html.Scripts) { if (!string.IsNullOrEmpty(script.Source)) { await AssertOk(script.Source); } } Assert.True(html.Links.Length == page.Links.Count(), $"Expected {page.Url} to have {page.Links.Count()} links but it had {html.Links.Length}"); foreach ((var link, var expectedLink) in html.Links.Zip(page.Links, Tuple.Create)) { IHtmlAnchorElement anchor = (IHtmlAnchorElement)link; if (string.Equals(anchor.Protocol, "about:")) { Assert.True(anchor.PathName.EndsWith(expectedLink, StringComparison.Ordinal), $"Expected next link on {page.Url} to be {expectedLink} but it was {anchor.PathName}: {html.Source.Text}"); await AssertOk(anchor.PathName); } else { Assert.True(string.Equals(anchor.Href, expectedLink), $"Expected next link to be {expectedLink} but it was {anchor.Href}."); var result = await RetryHelper.RetryRequest(async() => { return(await _httpClient.GetAsync(anchor.Href)); }, logger : NullLogger.Instance); Assert.True(IsSuccessStatusCode(result), $"{anchor.Href} is a broken link!"); } } }
public async Task HttpsHelloWorld(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl, ApplicationType applicationType) { var logger = new LoggerFactory() .AddConsole() .AddDebug() .CreateLogger($"HttpsHelloWorld:{serverType}:{runtimeFlavor}:{architecture}"); using (logger.BeginScope("HttpsHelloWorldTest")) { var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(applicationType), serverType, runtimeFlavor, architecture) { ApplicationBaseUriHint = applicationBaseUrl, EnvironmentName = "HttpsHelloWorld", // Will pick the Start class named 'StartupHttpsHelloWorld', ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("Https.config") : null, SiteName = "HttpsTestSite", // This is configured in the Https.config TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net451" : "netcoreapp1.0", ApplicationType = applicationType }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger)) { var deploymentResult = deployer.Deploy(); var handler = new WebRequestHandler(); handler.ServerCertificateValidationCallback = (a, b, c, d) => true; var httpClient = new HttpClient(handler) { 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(() => { return(httpClient.GetAsync(string.Empty)); }, logger, deploymentResult.HostShutdownToken, retryCount : 30); var responseText = await response.Content.ReadAsStringAsync(); try { Assert.Equal("Scheme:https; Original:http", responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } } } }
public async Task ResponseFormats(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl, Func <HttpClient, ILogger, Task> scenario, ApplicationType applicationType) { var logger = new LoggerFactory() .AddConsole() .CreateLogger(string.Format("ResponseFormats:{0}:{1}:{2}:{3}", serverType, runtimeFlavor, architecture, applicationType)); using (logger.BeginScope("ResponseFormatsTest")) { var deploymentParameters = new DeploymentParameters(Helpers.GetApplicationPath(applicationType), serverType, runtimeFlavor, architecture) { ApplicationBaseUriHint = applicationBaseUrl, EnvironmentName = "Responses", ServerConfigTemplateContent = Helpers.GetConfigContent(serverType, "Http.config", "nginx.conf"), SiteName = "HttpTestSite", // This is configured in the Http.config TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net451" : "netcoreapp1.0", ApplicationType = applicationType }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger)) { var deploymentResult = deployer.Deploy(); var httpClientHandler = new HttpClientHandler(); var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) }; // Request to base address and check if various parts of the body are rendered & measure the cold startup time. var response = await RetryHelper.RetryRequest(() => { return(httpClient.GetAsync(string.Empty)); }, logger, deploymentResult.HostShutdownToken); var responseText = await response.Content.ReadAsStringAsync(); try { Assert.Equal("Running", responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } await scenario(httpClient, logger); } } }
public async Task RunTestAndVerifyResponse( RuntimeFlavor runtimeFlavor, RuntimeArchitecture runtimeArchitechture, string applicationBaseUrl, string environmentName, string locale, string expectedText) { var logger = new LoggerFactory() .AddConsole() .CreateLogger(string.Format("Localization Test Site:{0}:{1}:{2}", ServerType.Kestrel, runtimeFlavor, runtimeArchitechture)); using (logger.BeginScope("LocalizationTest")) { var deploymentParameters = new DeploymentParameters(GetApplicationPath(), ServerType.Kestrel, runtimeFlavor, runtimeArchitechture) { ApplicationBaseUriHint = applicationBaseUrl, Command = "web", EnvironmentName = environmentName }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger)) { var deploymentResult = deployer.Deploy(); var cookie = new Cookie("ASPNET_CULTURE", "c=" + locale + "|uic=" + locale); var cookieContainer = new CookieContainer(); cookieContainer.Add(new Uri(deploymentResult.ApplicationBaseUri), cookie); var httpClientHandler = new HttpClientHandler(); httpClientHandler.CookieContainer = cookieContainer; var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(deploymentResult.ApplicationBaseUri) }; // Request to base address and check if various parts of the body are rendered & measure the cold startup time. var response = await RetryHelper.RetryRequest(() => { return(httpClient.GetAsync(string.Empty)); }, logger, deploymentResult.HostShutdownToken); var responseText = await response.Content.ReadAsStringAsync(); Console.WriteLine("Response Text " + responseText); Assert.Equal(expectedText, responseText); } } }
public async Task HelloWorld(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl, ServerType delegateServer) { var logger = new LoggerFactory() .AddConsole() .CreateLogger($"HelloWorld:{serverType}:{runtimeFlavor}:{architecture}:{delegateServer}"); using (logger.BeginScope("HelloWorldTest")) { var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(), serverType, runtimeFlavor, architecture) { ApplicationBaseUriHint = applicationBaseUrl, Command = delegateServer == ServerType.WebListener ? "weblistener" : "web", PublishWithNoSource = true, // Always publish with no source, otherwise it can't build and sign IISPlatformHandler EnvironmentName = "HelloWorld", // Will pick the Start class named 'StartupHelloWorld', ApplicationHostConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("Http.config") : null, SiteName = "HttpTestSite", // This is configured in the Http.config }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger)) { var deploymentResult = deployer.Deploy(); 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(() => { return(httpClient.GetAsync(string.Empty)); }, logger, deploymentResult.HostShutdownToken, retryCount : 30); var responseText = await response.Content.ReadAsStringAsync(); try { Assert.Equal("Hello World", responseText); } catch (XunitException) { logger.LogWarning(response.ToString()); logger.LogWarning(responseText); throw; } } } }
private async Task <string> RunRequest(string targetFramework, ApplicationType applicationType, string environment) { string responseText; var testName = $"ApplicationInsightsLoggingTest_{applicationType}"; using (StartLog(out var loggerFactory, testName)) { var logger = loggerFactory.CreateLogger(nameof(JavaScriptSnippetTest)); var deploymentParameters = new DeploymentParameters(GetApplicationPath(), ServerType.Kestrel, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { ApplicationBaseUriHint = "http://localhost:0", PublishApplicationBeforeDeployment = true, PreservePublishedApplicationForDebugging = PreservePublishedApplicationForDebugging, TargetFramework = "netcoreapp2.0", Configuration = GetCurrentBuildConfiguration(), ApplicationType = applicationType, EnvironmentName = environment, EnvironmentVariables = { new KeyValuePair <string, string>( "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", "Microsoft.AspNetCore.ApplicationInsights.HostingStartup"), new KeyValuePair <string, string>( "HOME", Path.Combine(GetApplicationPath(), "home")) }, }; using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) { var deploymentResult = await deployer.DeployAsync(); var httpClientHandler = new HttpClientHandler(); var httpClient = deploymentResult.CreateHttpClient(httpClientHandler); // 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() => await httpClient.GetAsync("/log"), 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"); responseText = await response.Content.ReadAsStringAsync(); } } return(responseText); }
public async Task Precompilation_WorksWithPageConventions(RuntimeFlavor flavor) { // Arrange using (var deployment = await Fixture.CreateDeploymentAsync(flavor)) { // Act var response = await RetryHelper.RetryRequest( () => deployment.HttpClient.GetAsync("/Auth/Index"), Fixture.Logger, retryCount : 5); // Assert Assert.Equal("/Login?ReturnUrl=%2FAuth%2FIndex", response.RequestMessage.RequestUri.PathAndQuery); } }
public async Task ContainsLinks(Page page) { var response = await RequestWithRetries(client => { var request = new HttpRequestMessage( HttpMethod.Get, new Uri(ListeningUri, page.Url)); return(client.SendAsync(request)); }, _httpClient); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var parser = new HtmlParser(); var html = await parser.ParseAsync(await response.Content.ReadAsStreamAsync()); foreach (IHtmlLinkElement styleSheet in html.GetElementsByTagName("link")) { Assert.Equal("stylesheet", styleSheet.Relation); await AssertOk(styleSheet.Href.Replace("about://", string.Empty)); } foreach (var script in html.Scripts) { if (!string.IsNullOrEmpty(script.Source)) { await AssertOk(script.Source); } } Assert.True(html.Links.Length == page.Links.Count(), $"Expected {page.Url} to have {page.Links.Count()} links but it had {html.Links.Length}"); foreach ((var link, var expectedLink) in html.Links.Zip(page.Links, Tuple.Create)) { IHtmlAnchorElement anchor = (IHtmlAnchorElement)link; if (string.Equals(anchor.Protocol, "about:")) { Assert.True(anchor.PathName.EndsWith(expectedLink), $"Expected next link on {page.Url} to be {expectedLink} but it was {anchor.PathName}."); await AssertOk(anchor.PathName); } else { Assert.True(string.Equals(anchor.Href, expectedLink), $"Expected next link to be {expectedLink} but it was {anchor.Href}."); var result = await RetryHelper.RetryRequest(async() => { return(await RequestWithRetries(client => client.GetAsync(anchor.Href), _httpClient)); }, logger : NullLogger.Instance); Assert.True(IsSuccessStatusCode(result), $"{anchor.Href} is a broken link!"); } } }
public static async Task <string> GetStringWithRetryAsync( this HttpClient httpClient, string url, ILogger logger) { var response = await RetryHelper.RetryRequest(() => httpClient.GetAsync(url), logger, retryCount : 5); var content = await response.Content.ReadAsStringAsync(); Assert.True(response.IsSuccessStatusCode, $"Failed to GET content from {url}. Status code {response.StatusCode}." + Environment.NewLine + content); return(content); }