Exemplo n.º 1
0
 public ProcessTrackTask(MainViewModel viewModelSource)
 {
     this.viewModelSource = viewModelSource;
     var tracker = new ProcessTracker();
     tracker.Start(10000);
     tracker.ProcessStarted += this.Tracker_ProcessStarted;
     tracker.ProcessStoped += Tracker_ProcessStoped;
 }
Exemplo n.º 2
0
 public Task <bool> StartServer(ProcessTracker server)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 3
0
        /// <summary>
        /// Run a single scenario. Passing 0 for scenarioIndex runs all scenarios.
        /// Once the scenario is done executing, the results are copied into the
        /// results directory.
        /// 
        /// If true is returned, then exitCode was assigned and can be checked. 
        /// If false is returned the value of exitCode is considered undefined.
        /// </summary>
        /// <param name="scenarioIndex">The scenario to run.</param>
        /// <returns>false if the job was not started, true if the job started and exitcode was assigned a value.</returns>
        private bool RunJob(int scenarioIndex, ref int exitCode)
        {
            bool rval = false;
            string envOpts = string.Format("/s /r:{0} {1}", scenarioIndex, EnvxFilePath);
            ProcessTracker tracker = new ProcessTracker(EnvExePath, envOpts);
            if (tracker.Start())
            {
                tracker.WaitForCompletion();
                logger.Debug(string.Format("Envision exited. Exit code: {0}", exitCode));
                rval = true;
            }

            exitCode = tracker.ExitCode;
            return rval;
        }
Exemplo n.º 4
0
    private async Task <(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(string contentRoot)
    {
        using (Logger.BeginScope("StartIISExpress"))
        {
            var iisExpressPath = GetIISExpressPath();

            for (var attempt = 0; attempt < MaximumAttempts; attempt++)
            {
                var uri  = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint);
                var port = uri.Port;
                if (port == 0)
                {
                    port = (uri.Scheme == "https") ? TestPortHelper.GetNextSSLPort() : TestPortHelper.GetNextPort();
                }

                Logger.LogInformation("Attempting to start IIS Express on port: {port}", port);
                PrepareConfig(contentRoot, port);

                var parameters = string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) ?
                                 string.Format(CultureInfo.InvariantCulture, "/port:{0} /path:\"{1}\" /trace:error /systray:false", uri.Port, contentRoot) :
                                 string.Format(CultureInfo.InvariantCulture, "/site:{0} /config:{1} /trace:error /systray:false", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation);

                Logger.LogInformation("Executing command : {iisExpress} {parameters}", iisExpressPath, parameters);

                var startInfo = new ProcessStartInfo
                {
                    FileName               = iisExpressPath,
                    Arguments              = parameters,
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true,
                    // VS sets current directory to C:\Program Files\IIS Express
                    WorkingDirectory = Path.GetDirectoryName(iisExpressPath)
                };

                AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables);

                Uri url     = null;
                var started = new TaskCompletionSource <bool>();

                var process = new Process()
                {
                    StartInfo = startInfo
                };
                process.OutputDataReceived += (sender, dataArgs) =>
                {
                    if (string.Equals(dataArgs.Data, UnableToStartIISExpressMessage, StringComparison.Ordinal))
                    {
                        // We completely failed to start and we don't really know why
                        started.TrySetException(new InvalidOperationException("Failed to start IIS Express"));
                    }
                    else if (string.Equals(dataArgs.Data, FailedToInitializeBindingsMessage, StringComparison.Ordinal))
                    {
                        started.TrySetResult(false);
                    }
                    else if (string.Equals(dataArgs.Data, IISExpressRunningMessage, StringComparison.Ordinal))
                    {
                        started.TrySetResult(true);
                    }
                    else if (!string.IsNullOrEmpty(dataArgs.Data))
                    {
                        var m = UrlDetectorRegex.Match(dataArgs.Data);
                        if (m.Success)
                        {
                            url = new Uri(m.Groups["url"].Value);
                        }
                    }
                };

                process.EnableRaisingEvents = true;
                var hostExitTokenSource = new CancellationTokenSource();
                process.Exited += (sender, e) =>
                {
                    Logger.LogInformation("iisexpress Process {pid} shut down", process.Id);

                    // If TrySetResult was called above, this will just silently fail to set the new state, which is what we want
                    started.TrySetException(new Exception($"Command exited unexpectedly with exit code: {process.ExitCode}"));

                    TriggerHostShutdown(hostExitTokenSource);
                };
                process.StartAndCaptureOutAndErrToLogger("iisexpress", Logger);
                Logger.LogInformation("iisexpress Process {pid} started", process.Id);

                if (process.HasExited)
                {
                    Logger.LogError("Host process {processName} {pid} exited with code {exitCode} or failed to start.", startInfo.FileName, process.Id, process.ExitCode);
                    throw new Exception("Failed to start host");
                }

                // Wait for the app to start
                // The timeout here is large, because we don't know how long the test could need. We cover a lot
                // of error cases above, but I want to make sure we eventually give up and don't hang the build
                // just in case we missed one -anurse
                if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(15)))
                {
                    Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", process.Id, port);

                    // Wait for the process to exit and try again
                    process.WaitForExit(30 * 1000);
                    await Task.Delay(1000); // Wait a second to make sure the socket is completely cleaned up
                }
                else
                {
                    _hostProcess = process;

                    // Ensure iisexpress.exe is killed if test process termination is non-graceful.
                    // Prevents locked files when stop debugging unit test.
                    ProcessTracker.Add(_hostProcess);

                    // cache the process start time for verifying log file name.
                    var _ = _hostProcess.StartTime;

                    Logger.LogInformation("Started iisexpress successfully. Process Id : {processId}, Port: {port}", _hostProcess.Id, port);
                    return(url : url, hostExitToken : hostExitTokenSource.Token);
                }
            }

            var message = $"Failed to initialize IIS Express after {MaximumAttempts} attempts to select a port";
            Logger.LogError(message);
            throw new TimeoutException(message);
        }
    }