public static string GetFailedProcessMessageOrEmpty(string step, Project project, ProcessEx process) { return process.HasExited ? $@"Project {project.ProjectArguments} failed to {step}. {process.GetFormattedOutput()}" : ""; }
public AspNetProcess( DevelopmentCertificate cert, ITestOutputHelper output, string workingDirectory, string dllPath, IDictionary <string, string> environmentVariables, bool published, bool hasListeningUri = true, bool usePublishedAppHost = false, ILogger logger = null) { _developmentCertificate = cert; _output = output; _httpClient = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true, UseCookies = true, CookieContainer = new CookieContainer(), ServerCertificateCustomValidationCallback = (request, certificate, chain, errors) => (certificate.Subject != "CN=localhost" && errors == SslPolicyErrors.None) || certificate?.Thumbprint == _developmentCertificate.CertificateThumbprint, }) { Timeout = TimeSpan.FromMinutes(2) }; output.WriteLine("Running ASP.NET Core application..."); string process; string arguments; if (published) { if (usePublishedAppHost) { // When publishingu used the app host to run the app. This makes it easy to consistently run for regular and single-file publish process = Path.ChangeExtension(dllPath, OperatingSystem.IsWindows() ? ".exe" : null); arguments = null; } else { process = DotNetMuxer.MuxerPathOrDefault(); arguments = $"exec {dllPath}"; } } else { process = DotNetMuxer.MuxerPathOrDefault(); arguments = "run --no-build"; } logger?.LogInformation($"AspNetProcess - process: {process} arguments: {arguments}"); var finalEnvironmentVariables = new Dictionary <string, string>(environmentVariables) { ["ASPNETCORE_Kestrel__Certificates__Default__Path"] = _developmentCertificate.CertificatePath, ["ASPNETCORE_Kestrel__Certificates__Default__Password"] = _developmentCertificate.CertificatePassword, }; Process = ProcessEx.Run(output, workingDirectory, process, arguments, envVars: finalEnvironmentVariables); logger?.LogInformation("AspNetProcess - process started"); if (hasListeningUri) { logger?.LogInformation("AspNetProcess - Getting listening uri"); ListeningUri = ResolveListeningUrl(output); logger?.LogInformation($"AspNetProcess - Got {ListeningUri}"); } }
internal async Task <ProcessEx> RunDotNetNewAsync( string templateName, string auth = null, string language = null, bool useLocalDB = false, bool noHttps = false, string[] args = null, // Used to set special options in MSBuild IDictionary <string, string> environmentVariables = null) { var hiveArg = $"--debug:custom-hive \"{TemplatePackageInstaller.CustomHivePath}\""; var argString = $"new {templateName} {hiveArg}"; environmentVariables ??= new Dictionary <string, string>(); if (!string.IsNullOrEmpty(auth)) { argString += $" --auth {auth}"; } if (!string.IsNullOrEmpty(language)) { argString += $" -lang {language}"; } if (useLocalDB) { argString += $" --use-local-db"; } if (noHttps) { argString += $" --no-https"; } if (args != null) { foreach (var arg in args) { argString += " " + arg; } } // Save a copy of the arguments used for better diagnostic error messages later. // We omit the hive argument and the template output dir as they are not relevant and add noise. ProjectArguments = argString.Replace(hiveArg, ""); argString += $" -o {TemplateOutputDir}"; // Only run one instance of 'dotnet new' at once, as a workaround for // https://github.com/aspnet/templating/issues/63 await DotNetNewLock.WaitAsync(); try { var execution = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), argString, environmentVariables); await execution.Exited; return(execution); } finally { DotNetNewLock.Release(); } }
internal async Task <ProcessResult> RunDotNetNewAsync( string templateName, string auth = null, string language = null, bool useLocalDB = false, bool noHttps = false, string[] args = null, // Used to set special options in MSBuild IDictionary <string, string> environmentVariables = null) { var hiveArg = $" --debug:disable-sdk-templates --debug:custom-hive \"{TemplatePackageInstaller.CustomHivePath}\""; var argString = $"new {templateName} {hiveArg}"; environmentVariables ??= new Dictionary <string, string>(); if (!string.IsNullOrEmpty(auth)) { argString += $" --auth {auth}"; } if (!string.IsNullOrEmpty(language)) { argString += $" -lang {language}"; } if (useLocalDB) { argString += $" --use-local-db"; } if (noHttps) { argString += $" --no-https"; } if (args != null) { foreach (var arg in args) { argString += " " + arg; } } // Save a copy of the arguments used for better diagnostic error messages later. // We omit the hive argument and the template output dir as they are not relevant and add noise. ProjectArguments = argString.Replace(hiveArg, ""); argString += $" -o {TemplateOutputDir}"; // Only run one instance of 'dotnet new' at once, as a workaround for // https://github.com/aspnet/templating/issues/63 await DotNetNewLock.WaitAsync(); try { Output.WriteLine("Acquired DotNetNewLock"); if (Directory.Exists(TemplateOutputDir)) { Output.WriteLine($"Template directory already exists, deleting contents of {TemplateOutputDir}"); Directory.Delete(TemplateOutputDir, recursive: true); } // Temporary while investigating why this process occasionally never runs or exits on Debian 9 environmentVariables.Add("COREHOST_TRACE", "1"); using var execution = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), argString, environmentVariables); await execution.Exited; return(new ProcessResult(execution)); } finally { DotNetNewLock.Release(); Output.WriteLine("Released DotNetNewLock"); } }
public AspNetProcess(ITestOutputHelper output, string workingDirectory, string projectName, string targetFrameworkOverride, bool publish) { _output = output; _httpClient = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true, UseCookies = true, CookieContainer = new CookieContainer(), ServerCertificateCustomValidationCallback = (m, c, ch, p) => true }); var now = DateTimeOffset.Now; new CertificateManager().EnsureAspNetCoreHttpsDevelopmentCertificate(now, now.AddYears(1)); var framework = string.IsNullOrEmpty(targetFrameworkOverride) ? DefaultFramework : targetFrameworkOverride; if (publish) { output.WriteLine("Publishing ASP.NET application..."); // Workaround for issue with runtime store not yet being published // https://github.com/aspnet/Home/issues/2254#issuecomment-339709628 var extraArgs = "-p:PublishWithAspNetCoreTargetManifest=false"; ProcessEx .Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), $"publish -c Release {extraArgs}") .WaitForExit(assertSuccess: true); workingDirectory = Path.Combine(workingDirectory, "bin", "Release", framework, "publish"); } else { output.WriteLine("Building ASP.NET application..."); ProcessEx .Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), "build --no-restore -c Debug") .WaitForExit(assertSuccess: true); } var envVars = new Dictionary <string, string> { { "ASPNETCORE_URLS", $"http://127.0.0.1:0;https://127.0.0.1:0" } }; if (!publish) { envVars["ASPNETCORE_ENVIRONMENT"] = "Development"; } output.WriteLine("Running ASP.NET application..."); if (framework.StartsWith("netcore")) { var dllPath = publish ? $"{projectName}.dll" : $"bin/Debug/{framework}/{projectName}.dll"; _process = ProcessEx.Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), $"exec {dllPath}", envVars: envVars); _listeningUri = GetListeningUri(output); } else { var exeFullPath = publish ? Path.Combine(workingDirectory, $"{projectName}.exe") : Path.Combine(workingDirectory, "bin", "Debug", framework, $"{projectName}.exe"); using (new AddFirewallExclusion(exeFullPath)) { _process = ProcessEx.Run(output, workingDirectory, exeFullPath, envVars: envVars); _listeningUri = GetListeningUri(output); } } }
public AspNetProcess(ITestOutputHelper output, string workingDirectory, string projectName, string targetFrameworkOverride, bool publish) { _output = output; _httpClient = new HttpClient(); var framework = string.IsNullOrEmpty(targetFrameworkOverride) ? DefaultFramework : targetFrameworkOverride; if (publish) { output.WriteLine("Publishing ASP.NET application..."); // Workaround for issue with runtime store not yet being published // https://github.com/aspnet/Home/issues/2254#issuecomment-339709628 var extraArgs = "-p:PublishWithAspNetCoreTargetManifest=false"; ProcessEx .Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), $"publish -c Release {extraArgs}") .WaitForExit(assertSuccess: true); workingDirectory = Path.Combine(workingDirectory, "bin", "Release", framework, "publish"); } else { output.WriteLine("Building ASP.NET application..."); ProcessEx .Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), "build --no-restore -c Debug") .WaitForExit(assertSuccess: true); } var envVars = new Dictionary <string, string> { { "ASPNETCORE_URLS", "http://127.0.0.1:0" } }; if (!publish) { envVars["ASPNETCORE_ENVIRONMENT"] = "Development"; } output.WriteLine("Running ASP.NET application..."); if (framework.StartsWith("netcore")) { var dllPath = publish ? $"{projectName}.dll" : $"bin/Debug/{framework}/{projectName}.dll"; _process = ProcessEx.Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), $"exec {dllPath}", envVars: envVars); } else { var exeFullPath = publish ? Path.Combine(workingDirectory, $"{projectName}.exe") : Path.Combine(workingDirectory, "bin", "Debug", framework, $"{projectName}.exe"); _process = ProcessEx.Run(output, workingDirectory, exeFullPath, envVars: envVars); } // Wait until the app is accepting HTTP requests output.WriteLine("Waiting until ASP.NET application is accepting connections..."); var listeningMessage = _process .OutputLinesAsEnumerable .Where(line => line != null) .FirstOrDefault(line => line.StartsWith(ListeningMessagePrefix, StringComparison.Ordinal)); Assert.True(!string.IsNullOrEmpty(listeningMessage), $"ASP.NET process exited without listening for requests.\nOutput: { _process.Output }\nError: { _process.Error }"); // Verify we have a valid URL to make requests to var listeningUrlString = listeningMessage.Substring(ListeningMessagePrefix.Length); _listeningUri = new Uri(listeningUrlString, UriKind.Absolute); output.WriteLine($"Detected that ASP.NET application is accepting connections on: {listeningUrlString}"); }