コード例 #1
0
ファイル: ExecutorService.cs プロジェクト: zyxws012/PTVS
 internal static void AttachDebugger(VisualStudioProxy app, ProcessOutput proc, PythonDebugMode debugMode, string debugSecret, int debugPort)
 {
     if (debugMode == PythonDebugMode.PythonOnly)
     {
         string qualifierUri = string.Format("tcp://{0}@localhost:{1}", debugSecret, debugPort);
         while (!app.AttachToProcess(proc, PythonRemoteDebugPortSupplierUnsecuredId, qualifierUri))
         {
             if (proc.Wait(TimeSpan.FromMilliseconds(500)))
             {
                 break;
             }
         }
     }
     else if (debugMode == PythonDebugMode.PythonAndNative)
     {
         var engines = new[] { PythonDebugEngineGuid, NativeDebugEngineGuid };
         while (!app.AttachToProcess(proc, engines))
         {
             if (proc.Wait(TimeSpan.FromMilliseconds(500)))
             {
                 break;
             }
         }
     }
 }
コード例 #2
0
        public bool AttachToProcess(ProcessOutput proc, Guid portSupplier, string transportQualifierUri)
        {
            var debugger3  = (EnvDTE90.Debugger3)DTE.Debugger;
            var transports = debugger3.Transports;

            EnvDTE80.Transport transport = null;
            for (int i = 1; i <= transports.Count; ++i)
            {
                var t = transports.Item(i);
                if (Guid.Parse(t.ID) == portSupplier)
                {
                    transport = t;
                    break;
                }
            }
            if (transport == null)
            {
                return(false);
            }

            var processes = debugger3.GetProcesses(transport, transportQualifierUri);

            if (processes.Count < 1)
            {
                return(false);
            }

            // Retry the attach itself 3 times before displaying a Retry/Cancel
            // dialog to the user.
            DTE.SuppressUI = true;
            try {
                try {
                    processes.Item(1).Attach();
                    return(true);
                } catch (COMException) {
                    if (proc.Wait(TimeSpan.FromMilliseconds(500)))
                    {
                        // Process exited while we were trying
                        return(false);
                    }
                }
            } finally {
                DTE.SuppressUI = false;
            }

            // Another attempt, but display UI.
            processes.Item(1).Attach();
            return(true);
        }
コード例 #3
0
        public bool AttachToProcess(ProcessOutput processOutput, EnvDTE.Process process, Guid[] engines = null)
        {
            // Retry the attach itself 3 times before displaying a Retry/Cancel
            // dialog to the user.
            var dte = GetDTE();

            dte.SuppressUI = true;
            try
            {
                try
                {
                    if (engines == null)
                    {
                        process.Attach();
                    }
                    else
                    {
                        var process3 = process as EnvDTE90.Process3;
                        if (process3 == null)
                        {
                            return(false);
                        }
                        process3.Attach2(engines.Select(engine => engine.ToString("B")).ToArray());
                    }
                    return(true);
                }
                catch (COMException)
                {
                    if (processOutput.Wait(TimeSpan.FromMilliseconds(500)))
                    {
                        // Process exited while we were trying
                        return(false);
                    }
                }
            }
            finally
            {
                dte.SuppressUI = false;
            }

            // Another attempt, but display UI.
            process.Attach();
            return(true);
        }
コード例 #4
0
ファイル: TestExecutor.cs プロジェクト: Frahmer/nodejstools
        private void RunTestCases(IEnumerable <TestCase> tests, IRunContext runContext, IFrameworkHandle frameworkHandle, NodejsProjectSettings settings)
        {
            // May be null, but this is handled by RunTestCase if it matters.
            // No VS instance just means no debugging, but everything else is
            // okay.
            if (tests.Count() == 0)
            {
                return;
            }

            using (var app = VisualStudioApp.FromEnvironmentVariable(NodejsConstants.NodeToolsProcessIdEnvironmentVariable))
            {
                var port     = 0;
                var nodeArgs = new List <string>();
                // .njsproj file path -> project settings
                var sourceToSettings = new Dictionary <string, NodejsProjectSettings>();
                var testObjects      = new List <TestCaseObject>();

                if (!File.Exists(settings.NodeExePath))
                {
                    frameworkHandle.SendMessage(TestMessageLevel.Error, "Interpreter path does not exist: " + settings.NodeExePath);
                    return;
                }

                // All tests being run are for the same test file, so just use the first test listed to get the working dir
                var testInfo   = new NodejsTestInfo(tests.First().FullyQualifiedName);
                var workingDir = Path.GetDirectoryName(CommonUtils.GetAbsoluteFilePath(settings.WorkingDir, testInfo.ModulePath));

                var nodeVersion = Nodejs.GetNodeVersion(settings.NodeExePath);

                // We can only log telemetry when we're running in VS.
                // Since the required assemblies are not on disk if we're not running in VS, we have to reference them in a separate method
                // this way the .NET framework only tries to load the assemblies when we actually need them.
                if (app != null)
                {
                    LogTelemetry(tests.Count(), nodeVersion, runContext.IsBeingDebugged);
                }

                foreach (var test in tests)
                {
                    if (_cancelRequested.WaitOne(0))
                    {
                        break;
                    }

                    if (settings == null)
                    {
                        frameworkHandle.SendMessage(
                            TestMessageLevel.Error,
                            $"Unable to determine interpreter to use for {test.Source}.");
                        frameworkHandle.RecordEnd(test, TestOutcome.Failed);
                    }

                    var args = new List <string>();
                    args.AddRange(GetInterpreterArgs(test, workingDir, settings.ProjectRootDir));

                    // Fetch the run_tests argument for starting node.exe if not specified yet
                    if (nodeArgs.Count == 0 && args.Count > 0)
                    {
                        nodeArgs.Add(args[0]);
                    }

                    testObjects.Add(new TestCaseObject(args[1], args[2], args[3], args[4], args[5]));
                }

                if (runContext.IsBeingDebugged && app != null)
                {
                    app.GetDTE().Debugger.DetachAll();
                    // Ensure that --debug-brk is the first argument
                    nodeArgs.InsertRange(0, GetDebugArgs(out port));
                }

                _nodeProcess = ProcessOutput.Run(
                    settings.NodeExePath,
                    nodeArgs,
                    settings.WorkingDir,
                    /* env */ null,
                    /* visible */ false,
                    /* redirector */ new TestExecutionRedirector(this.ProcessTestRunnerEmit),
                    /* quote args */ false);

                if (runContext.IsBeingDebugged && app != null)
                {
                    try
                    {
                        //the '#ping=0' is a special flag to tell VS node debugger not to connect to the port,
                        //because a connection carries the consequence of setting off --debug-brk, and breakpoints will be missed.
                        var qualifierUri = string.Format("tcp://localhost:{0}#ping=0", port);
                        while (!app.AttachToProcess(_nodeProcess, NodejsRemoteDebugPortSupplierUnsecuredId, qualifierUri))
                        {
                            if (_nodeProcess.Wait(TimeSpan.FromMilliseconds(500)))
                            {
                                break;
                            }
                        }
#if DEBUG
                    }
                    catch (COMException ex)
                    {
                        frameworkHandle.SendMessage(TestMessageLevel.Error, "Error occurred connecting to debuggee.");
                        frameworkHandle.SendMessage(TestMessageLevel.Error, ex.ToString());
                        KillNodeProcess();
                    }
#else
                    } catch (COMException) {
コード例 #5
0
        private void RunTestCase(VisualStudioApp app, IFrameworkHandle frameworkHandle, IRunContext runContext, TestCase test, Dictionary <string, NodejsProjectSettings> sourceToSettings)
        {
            var testResult = new TestResult(test);

            frameworkHandle.RecordStart(test);
            testResult.StartTime = DateTimeOffset.Now;
            NodejsProjectSettings settings;

            if (!sourceToSettings.TryGetValue(test.Source, out settings))
            {
                sourceToSettings[test.Source] = settings = LoadProjectSettings(test.Source);
            }
            if (settings == null)
            {
                frameworkHandle.SendMessage(
                    TestMessageLevel.Error,
                    "Unable to determine interpreter to use for " + test.Source);
                RecordEnd(
                    frameworkHandle,
                    test,
                    testResult,
                    null,
                    "Unable to determine interpreter to use for " + test.Source,
                    TestOutcome.Failed);
                return;
            }

            NodejsTestInfo testInfo = new NodejsTestInfo(test.FullyQualifiedName);
            List <string>  args     = new List <string>();
            int            port     = 0;

            if (runContext.IsBeingDebugged && app != null)
            {
                app.GetDTE().Debugger.DetachAll();
                args.AddRange(GetDebugArgs(settings, out port));
            }

            var workingDir = Path.GetDirectoryName(CommonUtils.GetAbsoluteFilePath(settings.WorkingDir, testInfo.ModulePath));

            args.AddRange(GetInterpreterArgs(test, workingDir, settings.ProjectRootDir));

            //Debug.Fail("attach debugger");
            if (!File.Exists(settings.NodeExePath))
            {
                frameworkHandle.SendMessage(TestMessageLevel.Error, "Interpreter path does not exist: " + settings.NodeExePath);
                return;
            }
            lock (_syncObject) {
                _nodeProcess = ProcessOutput.Run(
                    settings.NodeExePath,
                    args,
                    workingDir,
                    null,
                    false,
                    null,
                    false);

#if DEBUG
                frameworkHandle.SendMessage(TestMessageLevel.Informational, "cd " + workingDir);
                frameworkHandle.SendMessage(TestMessageLevel.Informational, _nodeProcess.Arguments);
#endif

                _nodeProcess.Wait(TimeSpan.FromMilliseconds(500));
                if (runContext.IsBeingDebugged && app != null)
                {
                    try {
                        //the '#ping=0' is a special flag to tell VS node debugger not to connect to the port,
                        //because a connection carries the consequence of setting off --debug-brk, and breakpoints will be missed.
                        string qualifierUri = string.Format("tcp://localhost:{0}#ping=0", port);
                        while (!app.AttachToProcess(_nodeProcess, NodejsRemoteDebugPortSupplierUnsecuredId, qualifierUri))
                        {
                            if (_nodeProcess.Wait(TimeSpan.FromMilliseconds(500)))
                            {
                                break;
                            }
                        }
#if DEBUG
                    } catch (COMException ex) {
                        frameworkHandle.SendMessage(TestMessageLevel.Error, "Error occurred connecting to debuggee.");
                        frameworkHandle.SendMessage(TestMessageLevel.Error, ex.ToString());
                        KillNodeProcess();
                    }
#else
                    } catch (COMException) {
コード例 #6
0
        private void RunTestCase(VisualStudioApp app, IFrameworkHandle frameworkHandle, IRunContext runContext, TestCase test, Dictionary <string, NodejsProjectSettings> sourceToSettings)
        {
            var testResult = new TestResult(test);

            frameworkHandle.RecordStart(test);
            testResult.StartTime = DateTimeOffset.Now;
            NodejsProjectSettings settings;

            if (!sourceToSettings.TryGetValue(test.Source, out settings))
            {
                sourceToSettings[test.Source] = settings = LoadProjectSettings(test.Source);
            }
            if (settings == null)
            {
                frameworkHandle.SendMessage(
                    TestMessageLevel.Error,
                    "Unable to determine interpreter to use for " + test.Source);
                RecordEnd(
                    frameworkHandle,
                    test,
                    testResult,
                    null,
                    "Unable to determine interpreter to use for " + test.Source,
                    TestOutcome.Failed);
                return;
            }

#if DEV15
            // VS 2017 doesn't install some assemblies to the GAC that are needed to work with the
            // debugger, and as the tests don't execute in the devenv.exe process, those assemblies
            // fail to load - so load them manually from PublicAssemblies.

            // Use the executable name, as this is only needed for the out of proc test execution
            // that may interact with the debugger (vstest.executionengine.x86.exe).
            string currentProc = Process.GetCurrentProcess().MainModule.FileName;
            if (Path.GetFileName(currentProc).ToLowerInvariant().Equals("vstest.executionengine.x86.exe"))
            {
                string baseDir          = Path.GetDirectoryName(currentProc);
                string publicAssemblies = Path.Combine(baseDir, "..\\..\\..\\PublicAssemblies");

                Assembly.LoadFrom(Path.Combine(publicAssemblies, "Microsoft.VisualStudio.OLE.Interop.dll"));
                Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte90.dll"));
                Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte80.dll"));
                Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte.dll"));
            }
#endif

            NodejsTestInfo testInfo = new NodejsTestInfo(test.FullyQualifiedName);
            List <string>  args     = new List <string>();
            int            port     = 0;
            if (runContext.IsBeingDebugged && app != null)
            {
                app.GetDTE().Debugger.DetachAll();
                args.AddRange(GetDebugArgs(settings, out port));
            }

            var workingDir = Path.GetDirectoryName(CommonUtils.GetAbsoluteFilePath(settings.WorkingDir, testInfo.ModulePath));
            args.AddRange(GetInterpreterArgs(test, workingDir, settings.ProjectRootDir));

            //Debug.Fail("attach debugger");
            if (!File.Exists(settings.NodeExePath))
            {
                frameworkHandle.SendMessage(TestMessageLevel.Error, "Interpreter path does not exist: " + settings.NodeExePath);
                return;
            }
            lock (_syncObject) {
                _nodeProcess = ProcessOutput.Run(
                    settings.NodeExePath,
                    args,
                    workingDir,
                    null,
                    false,
                    null,
                    false);

#if DEBUG
                frameworkHandle.SendMessage(TestMessageLevel.Informational, "cd " + workingDir);
                frameworkHandle.SendMessage(TestMessageLevel.Informational, _nodeProcess.Arguments);
#endif

                _nodeProcess.Wait(TimeSpan.FromMilliseconds(500));
                if (runContext.IsBeingDebugged && app != null)
                {
                    try {
                        //the '#ping=0' is a special flag to tell VS node debugger not to connect to the port,
                        //because a connection carries the consequence of setting off --debug-brk, and breakpoints will be missed.
                        string qualifierUri = string.Format(CultureInfo.InvariantCulture, "tcp://localhost:{0}#ping=0", port);
                        while (!app.AttachToProcess(_nodeProcess, NodejsRemoteDebugPortSupplierUnsecuredId, qualifierUri))
                        {
                            if (_nodeProcess.Wait(TimeSpan.FromMilliseconds(500)))
                            {
                                break;
                            }
                        }
#if DEBUG
                    } catch (COMException ex) {
                        frameworkHandle.SendMessage(TestMessageLevel.Error, "Error occurred connecting to debuggee.");
                        frameworkHandle.SendMessage(TestMessageLevel.Error, ex.ToString());
                        KillNodeProcess();
                    }
#else
                    } catch (COMException) {