Ejemplo n.º 1
0
        public static string GetFailedProcessMessageOrEmpty(string step, Project project, ProcessEx process)
        {
            return process.HasExited ? $@"Project {project.ProjectArguments} failed to {step}.
{process.GetFormattedOutput()}" : "";
        }
Ejemplo n.º 2
0
        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}");
            }
        }
Ejemplo n.º 3
0
        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();
            }
        }
Ejemplo n.º 4
0
        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");
            }
        }
Ejemplo n.º 5
0
        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);
                }
            }
        }
Ejemplo n.º 6
0
        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}");
        }