示例#1
0
            public void Run()
            {
                if (!File.Exists(_settings.InterpreterPath))
                {
                    Error(Strings.Test_InterpreterDoesNotExist.FormatUI(_settings.InterpreterPath));
                    return;
                }
                try {
                    ExecutorService.DetachFromSillyManagedProcess(_app, _debugMode);

                    var pythonPath = InitializeEnvironment();

                    string testList = null;
                    // For a small set of tests, we'll pass them on the command
                    // line. Once we exceed a certain (arbitrary) number, create
                    // a test list on disk so that we do not overflow the
                    // 32K argument limit.
                    if (_tests.Length > 5)
                    {
                        testList = TestUtils.CreateTestListFile(GetTestCases().Select(pair => pair.Key));
                    }
                    var arguments = GetArguments(testList);

                    ////////////////////////////////////////////////////////////
                    // Do the test run
                    _connected.Reset();
                    using (var proc = ProcessOutput.Run(
                               _settings.InterpreterPath,
                               arguments,
                               _settings.WorkingDirectory,
                               _env,
                               _showConsole,
                               null
                               )) {
                        bool killed = false;

                        Info("cd " + _settings.WorkingDirectory);
                        Info("set " + pythonPath.Key + "=" + pythonPath.Value);
                        Info(proc.Arguments);

                        // If there's an error in the launcher script,
                        // it will terminate without connecting back.
                        WaitHandle.WaitAny(new WaitHandle[] { _connected, proc.WaitHandle });
                        bool processConnected = _connected.WaitOne(1);

                        if (!processConnected && proc.ExitCode.HasValue)
                        {
                            // Process has already exited
                            proc.Wait();
                            Error(Strings.Test_FailedToStartExited);
                            if (proc.StandardErrorLines.Any())
                            {
                                foreach (var line in proc.StandardErrorLines)
                                {
                                    Error(line);
                                }
                            }

                            foreach (var test in GetTestCases())
                            {
                                _frameworkHandle.RecordStart(test.Value);
                                _frameworkHandle.RecordResult(new TestResult(test.Value)
                                {
                                    Outcome      = TestOutcome.Skipped,
                                    ErrorMessage = Strings.Test_NotRun
                                });
                            }

                            killed = true;
                        }

                        if (!killed && _debugMode != PythonDebugMode.None)
                        {
                            try {
                                ExecutorService.AttachDebugger(_app, proc, _debugMode, _debugSecret, _debugPort);
                            } catch (COMException ex) {
                                Error(Strings.Test_ErrorConnecting);
                                DebugError(ex.ToString());
                                try {
                                    proc.Kill();
                                } catch (InvalidOperationException) {
                                    // Process has already exited
                                }
                                killed = true;
                            }
                        }


                        // https://pytools.codeplex.com/workitem/2290
                        // Check that proc.WaitHandle was not null to avoid crashing if
                        // a test fails to start running. We will report failure and
                        // send the error message from stdout/stderr.
                        var handles = new WaitHandle[] { _cancelRequested, proc.WaitHandle, _done };
                        if (handles[1] == null)
                        {
                            killed = true;
                        }

                        if (!killed)
                        {
                            switch (WaitHandle.WaitAny(handles))
                            {
                            case 0:
                                // We've been cancelled
                                try {
                                    proc.Kill();
                                } catch (InvalidOperationException) {
                                    // Process has already exited
                                }
                                killed = true;
                                break;

                            case 1:
                                // The process has exited, give a chance for our comm channel
                                // to be flushed...
                                handles = new WaitHandle[] { _cancelRequested, _done };
                                if (WaitHandle.WaitAny(handles, 10000) != 1)
                                {
                                    Warning(Strings.Test_NoTestFinishedNotification);
                                }
                                break;

                            case 2:
                                // We received the done event
                                break;
                            }
                        }
                    }
                    if (File.Exists(testList))
                    {
                        try {
                            File.Delete(testList);
                        } catch (IOException) {
                        }
                    }
                } catch (Exception e) {
                    Error(e.ToString());
                }
            }