Beispiel #1
0
 private void CopySource()
 {
     try
     {
         this.WriteLine("Creating instance of debuggee by copying source.");
         FileUtilities.DirectoryCopy(this.DebuggeeRoot, this.DebuggeeInstance, true);
     }
     catch (IOException ex)
     {
         this.WriteLine("Error copying debuggee folder. Copying from '{0}' to '{1}'.", this.DebuggeeRoot, this.DebuggeeInstance);
         this.WriteLine(UDebug.ExceptionToString(ex));
         throw;
     }
 }
Beispiel #2
0
        /// <summary>
        /// Check for abandoned files or processes
        /// </summary>
        /// <param name="throwOnFailure">Fail the test if abandoned artifacts found</param>
        private void CheckDebuggerArtifacts(bool throwOnFailure)
        {
            try
            {
                if (string.IsNullOrEmpty(this.engineLogPath) || !File.Exists(this.engineLogPath))
                {
                    return;
                }

                string engineLogContent = File.ReadAllText(this.engineLogPath);

                // Add the MIEngine log to the test log (if it is enabled)
                if (!throwOnFailure && DiagnosticsSettings.LogMIEngine)
                {
                    this.Comment("Engine Log");
                    this.WriteLine(engineLogContent);
                }

                // Parse the mi engine's log to find associated temp files and debugger pids
                // This only checks for any process ids or files logged by the mi engine
                // and may not be a complete list.
                List <string> tempFiles      = new List <string>(3);
                List <int>    associatedPids = new List <int>(2);
                foreach (Match match in EngineLogRegEx.Matches(engineLogContent))
                {
                    string tempFile    = match.Groups?["tempFile"]?.Value;
                    string shellPid    = match.Groups?["shellPid"]?.Value;
                    string debuggerPid = match.Groups?["debuggerPid"]?.Value;

                    if (!string.IsNullOrEmpty(tempFile))
                    {
                        tempFiles.Add(tempFile);
                    }
                    else if (!string.IsNullOrEmpty(shellPid))
                    {
                        associatedPids.Add(int.Parse(shellPid, CultureInfo.InvariantCulture));
                    }
                    else if (!string.IsNullOrEmpty(debuggerPid))
                    {
                        associatedPids.Add(int.Parse(debuggerPid, CultureInfo.InvariantCulture));
                    }
                }

                // Check for abandoned temp files
                foreach (string tempFile in tempFiles)
                {
                    if (File.Exists(tempFile))
                    {
                        this.WriteLine("ERROR: Debug Adapter abandoned temp file: " + tempFile);
                        TryDeleteFile(tempFile);
                        Assert.False(throwOnFailure, "ERROR: Debug Adapter abandoned temp file: " + tempFile);
                    }
                }

                // Check for abandoned processes
                foreach (int associatedPid in associatedPids)
                {
                    if (ProcessHelper.IsProcessRunning(associatedPid))
                    {
                        this.WriteLine("ERROR: Debug Adapter abandoned process: " + associatedPid.ToString(CultureInfo.InvariantCulture));
                        ProcessHelper.KillProcess(associatedPid, recurse: true);
                        Assert.False(throwOnFailure, "ERROR: Debug Adapter abandoned process: " + associatedPid.ToString(CultureInfo.InvariantCulture));
                    }
                }
            }
            catch (Exception ex)
            {
                this.WriteLine("Error checking engine log. {0}", UDebug.ExceptionToString(ex));
            }
        }
Beispiel #3
0
        /// <summary>
        /// Runs a command against the debugger.
        /// </summary>
        /// <param name="command">The command to run.</param>
        /// <param name="expectedEvents">[OPTIONAL] If the command causes an event to occur, pass the expected event(s)</param>
        private void Run(DarRunner darRunner, ILoggingComponent log, params IEvent[] expectedEvents)
        {
            Parameter.ThrowIfNull(darRunner, nameof(darRunner));

            log?.WriteLine("Running command {0}", this.ToString());
            log?.WriteLine("Command '{0}' expecting response: {1}", this.Name, this.ExpectedResponse.ToString());

            DebugAdapterResponse darCommandResponse = GetDarResponse(this.ExpectedResponse);
            DebugAdapterCommand  darCommand         = new DebugAdapterCommand(
                this.Name,
                this.Args,
                new[] { darCommandResponse });
            List <Tuple <DebugAdapterResponse, IEvent> > darEventMap = new List <Tuple <DebugAdapterResponse, IEvent> >(expectedEvents.Length);

            // Add additional expected events to match if requested
            if (expectedEvents != null && expectedEvents.Length > 0)
            {
                if (expectedEvents.Length > 1)
                {
                    log?.WriteLine("Command '{0}' expecting {1} events:", this.Name, expectedEvents.Length);
                }

                foreach (var expectedEvent in expectedEvents)
                {
                    DebugAdapterResponse darEventResponse = GetDarResponse(expectedEvent);
                    darCommand.ExpectedResponses.Add(darEventResponse);
                    darEventMap.Add(Tuple.Create(darEventResponse, expectedEvent));

                    // Debug info for expected response
                    string eventMessage = expectedEvents.Length > 1 ? "  - {1}" : "Command '{0}' expecting event: {1}";
                    log?.WriteLine(eventMessage, this.Name, expectedEvent.ToString());
                }
            }

            // Allow the command to override the timeout
            int overrideTimeout = Convert.ToInt32(this.Timeout.TotalMilliseconds);
            int savedTimeout    = darRunner.ResponseTimeout;

            try
            {
                if (overrideTimeout > 0)
                {
                    darRunner.ResponseTimeout = overrideTimeout;
                    log?.WriteLine("Command '{0}' timeout set to {1:n0} seconds.", this.Name, this.Timeout.TotalSeconds);
                }

                darCommand.Run(darRunner);

                // Allow the command to retrieve properties from the actual matched response.
                string responseJson = JsonConvert.SerializeObject(darCommandResponse.Match);
                if (!string.IsNullOrWhiteSpace(responseJson))
                {
                    this.ProcessActualResponse(new ActualResponse(responseJson));
                }

                // Allow the events to retrieve properties from the actual event.
                foreach (var darEvent in darEventMap)
                {
                    string eventJson = JsonConvert.SerializeObject(darEvent.Item1.Match);
                    darEvent.Item2.ProcessActualResponse(new ActualResponse(eventJson));
                }
            }
            catch (Exception ex)
            {
                // Add information to the log when the exception occurs
                log?.WriteLine("ERROR: Running command '{0}'. Exception thrown.", this.Name);
                log?.WriteLine(UDebug.ExceptionToString(ex));

                // The DARException is not serializable, create a new exception
                if (ex is DARException)
                {
                    throw new RunnerException(ex.Message);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                if (overrideTimeout > 0)
                {
                    darRunner.ResponseTimeout = savedTimeout;
                }
            }
        }