Beispiel #1
0
  /**
   * Adds a set of arguments used to wrap executed file with unittest runner.
   *
   * @param actualRun in an actual run we'll start the xml-rpc server.
   * @param coverageRun whether we should add the flags to do a coverage run.
   */
  private void addUnittestArgs(List<String> cmdArgs, boolean actualRun, boolean coverageRun)
      throws CoreException {
    if (isUnittest()) {

      // The tests are either written to a configuration file or passed as a parameter.
      String configurationFile =
          this.configuration.getAttribute(Constants.ATTR_UNITTEST_CONFIGURATION_FILE, "");
      if (configurationFile.length() > 0) {
        cmdArgs.add("--config_file");
        if (actualRun) {
          // We should write the contents to a temporary file (because it may be too long, so,
          // always write
          // to a file and read from it later on).
          File tempFile = PydevPlugin.getDefault().getTempFile("custom_pydev_unittest_launch_");
          try {
            OutputStream fileOutputStream = new FileOutputStream(tempFile);
            try {
              try {
                fileOutputStream.write(configurationFile.getBytes());
              } catch (IOException e) {
                throw new CoreException(
                    PydevPlugin.makeStatus(IStatus.ERROR, "Error writing to: " + tempFile, e));
              }
            } finally {
              fileOutputStream.close();
            }
          } catch (Exception e) {
            if (e instanceof CoreException) {
              throw (CoreException) e;
            }
            throw new CoreException(
                PydevPlugin.makeStatus(IStatus.ERROR, "Error writing to: " + tempFile, e));
          }
          cmdArgs.add(tempFile.toString());
        } else {
          cmdArgs.add(configurationFile);
        }
      } else {
        String tests = this.configuration.getAttribute(Constants.ATTR_UNITTEST_TESTS, "");
        if (tests.length() > 0) {
          cmdArgs.add("--tests");
          cmdArgs.add(tests);
        }
      }

      if (PyUnitPrefsPage2.getUsePyUnitView()) {
        // If we want to use the PyUnitView, we need to get the port used so that the python side
        // can connect.
        cmdArgs.add("--port");
        if (actualRun) {
          cmdArgs.add(String.valueOf(getPyUnitServer().getPort()));
        } else {
          cmdArgs.add("0");
        }
      }

      if (coverageRun) {
        cmdArgs.add("--coverage_output_dir");
        cmdArgs.add(PyCoverage.getCoverageDirLocation().getAbsolutePath());

        cmdArgs.add("--coverage_include");
        cmdArgs.add(PyCodeCoverageView.getChosenDir().getLocation().toOSString());

        if (actualRun) {
          IPreferenceStore prefs = PydevPrefs.getPreferenceStore();
          int testRunner = prefs.getInt(PyUnitPrefsPage2.TEST_RUNNER);

          switch (testRunner) {
            case PyUnitPrefsPage2.TEST_RUNNER_NOSE:
              RunInUiThread.async(
                  new Runnable() {

                    public void run() {
                      PyDialogHelpers.openWarningWithIgnoreToggle(
                          "Notes for coverage with the nose test runner.",
                          "Note1: When using the coverage with the nose test runner, "
                              + "please don't pass any specific parameter related to "
                              + "the run in the arguments, as that's already handled by PyDev "
                              + "(i.e.: don't use the builtin cover plugin from nose).\n"
                              + "\n"
                              + "Note2: It's currently not possible to use coverage with the multi-process "
                              + "plugin in nose.",
                          "KEY_COVERAGE_WITH_NOSE_TEST_RUNNER");
                    }
                  });

              break;
            case PyUnitPrefsPage2.TEST_RUNNER_PY_TEST:
              RunInUiThread.async(
                  new Runnable() {

                    public void run() {
                      PyDialogHelpers.openCritical(
                          "PyUnit coverage not compatible with the Py.test test runner.",
                          "Currently the PyDev PyUnit integration is not able to provide coverage "
                              + "info using the py.test test runner (please enter a "
                              + "feature request if you'd like that added)\n"
                              + "\n"
                              + "Note: the run will be continued anyways (without gathering coverage info).");
                    }
                  });
              break;
          }
        }
      }

      // Last thing: nose parameters or parameters the user configured.
      for (String s :
          parseStringIntoList(
              PyUnitPrefsPage2.getTestRunnerParameters(this.configuration, this.project))) {
        cmdArgs.add(s);
      }
    }
  }
Beispiel #2
0
  /**
   * Create a command line for launching.
   *
   * @param actualRun if true it'll make the variable substitution and start the listen connector in
   *     the case of a debug session.
   * @return command line ready to be exec'd
   * @throws CoreException
   * @throws JDTNotAvailableException
   */
  public String[] getCommandLine(boolean actualRun) throws CoreException, JDTNotAvailableException {
    List<String> cmdArgs = new ArrayList<String>();

    if (isJython()) {
      // "java.exe" -classpath "C:\bin\jython21\jython.jar" org.python.util.jython script %ARGS%
      String javaLoc = JavaVmLocationFinder.findDefaultJavaExecutable().getAbsolutePath();
      if (!InterpreterInfo.isJythonExecutable(interpreter.toOSString())) {
        throw new RuntimeException(
            "The jython jar must be specified as the interpreter to run. Found: " + interpreter);
      }
      cmdArgs.add(javaLoc);

      // some nice things on the classpath config: http://mindprod.com/jgloss/classpath.html
      cmdArgs.add("-classpath");
      String cpath;

      // TODO: add some option in the project so that the user can choose to use the
      // classpath specified in the java project instead of the pythonpath itself

      //            if (project.getNature(Constants.JAVA_NATURE) != null){
      //                cpath  = getClasspath(JavaCore.create(project));
      //            } else {
      cpath = interpreter + SimpleRunner.getPythonPathSeparator() + pythonpathUsed;
      //            }
      cmdArgs.add(cpath);
      cmdArgs.add(
          "-Dpython.path="
              + pythonpathUsed); // will be added to the env variables in the run (check if this
      // works on all platforms...)

      addVmArgs(cmdArgs);

      if (isDebug) {
        // This was removed because it cannot be used. See:
        // http://bugs.jython.org/issue1438
        // cmdArgs.add("-Dpython.security.respectJavaAccessibility=false");

        cmdArgs.add("org.python.util.jython");
        addDebugArgs(cmdArgs, "jython", actualRun);
      } else {
        cmdArgs.add("org.python.util.jython");
      }

    } else {
      // python or iron python

      cmdArgs.add(interpreter.toOSString());
      // Next option is for unbuffered stdout, otherwise Eclipse will not see any output until done
      cmdArgs.add("-u");

      addVmArgs(cmdArgs);
      if (isDebug && isIronpython()) {
        addIronPythonDebugVmArgs(cmdArgs);
      }

      addDebugArgs(cmdArgs, "python", actualRun);
    }

    // Check if we should do code-coverage...
    boolean coverageRun = PyCoveragePreferences.getAllRunsDoCoverage();
    if (coverageRun && isDebug) {
      if (actualRun) {
        RunInUiThread.async(
            new Runnable() {

              public void run() {
                PyDialogHelpers.openWarning(
                    "Conflicting options: coverage with debug.",
                    "Making a debug run with coverage enabled will not yield the expected results.\n\n"
                        + "They'll conflict because both use the python tracing facility (i.e.: sys.settrace()).\n"
                        + "\n"
                        + "To debug a coverage run, do a regular run and use the remote debugger "
                        + "(but note that the coverage will stop when it's enabled).\n"
                        + "\n"
                        + "Note: the run will be continued anyways.");
              }
            });
      }
    }

    if (isUnittest()) {
      cmdArgs.add(getRunFilesScript());
    } else {
      if (coverageRun) {
        // Separate support (unittest has the coverage support builtin).
        cmdArgs.add(getCoverageScript());
        cmdArgs.add(PyCoverage.getCoverageFileLocation().getAbsolutePath());
        cmdArgs.add("run");
        cmdArgs.add("--source");
        cmdArgs.add(PyCodeCoverageView.getChosenDir().getLocation().toOSString());
      }
    }

    for (IPath p : resource) {
      cmdArgs.add(p.toOSString());
    }

    if (!isUnittest()) {
      // The program arguments are not used when running a unittest (excluded from the tab group in
      // favor
      // of a way to overriding the default unittest arguments).
      String runArguments[] = null;
      if (actualRun && arguments != null) {
        String expanded =
            getStringSubstitution(PythonNature.getPythonNature(project))
                .performStringSubstitution(arguments);
        runArguments = parseStringIntoList(expanded);
      }

      for (int i = 0; runArguments != null && i < runArguments.length; i++) {
        cmdArgs.add(runArguments[i]);
      }

    } else {
      // Last thing (first the files and last the special parameters the user passed -- i.e.: nose
      // parameters)
      addUnittestArgs(cmdArgs, actualRun, coverageRun);
    }

    String[] retVal = new String[cmdArgs.size()];
    cmdArgs.toArray(retVal);

    if (actualRun) {
      CreatedCommandLineParams createdCommandLineParams =
          new CreatedCommandLineParams(retVal, coverageRun);
      // Provide a way for clients to alter the command line.
      List<Object> participants =
          ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_COMMAND_LINE_PARTICIPANT);
      for (Object object : participants) {
        try {
          IPyCommandLineParticipant c = (IPyCommandLineParticipant) object;
          createdCommandLineParams = c.updateCommandLine(createdCommandLineParams);
        } catch (Exception e) {
          Log.log(e);
        }
      }

      retVal = createdCommandLineParams.cmdLine;
      PythonRunnerCallbacks.onCreatedCommandLine.call(createdCommandLineParams);
    }

    return retVal;
  }