/** {@inheritDoc} */ @Override public WorkerRunnable createWorkerRunnable(final Object testRunner) throws EngineException { if (testRunner instanceof PyObject) { final PyObject pyTestRunner = (PyObject) testRunner; if (pyTestRunner.isCallable()) { return new JythonWorkerRunnable(pyTestRunner); } } throw new JythonScriptExecutionException("testRunner object is not callable"); }
/** {@inheritDoc} */ @Override public WorkerRunnable createWorkerRunnable() throws EngineException { final PyObject pyTestRunner; try { // Script does per-thread initialisation here and // returns a callable object. pyTestRunner = m_testRunnerFactory.__call__(); } catch (final PyException e) { throw new JythonScriptExecutionException("creating per-thread TestRunner object", e); } if (!pyTestRunner.isCallable()) { throw new JythonScriptExecutionException( "The result of '" + TEST_RUNNER_CALLABLE_NAME + "()' is not callable"); } return new JythonWorkerRunnable(pyTestRunner); }
/** * Constructor for JythonScriptEngine. * * @param pySystemState Python system state. * @throws EngineException If the script engine could not be created. */ public JythonScriptEngine(final ScriptLocation script) throws EngineException { // Work around Jython issue 1894900. // If the python.cachedir has not been specified, and Jython is loaded // via the manifest classpath or the jar in the lib directory is // explicitly mentioned in the CLASSPATH, then set the cache directory to // be alongside jython.jar. if (System.getProperty(PYTHON_HOME) == null && System.getProperty(PYTHON_CACHEDIR) == null) { final String classpath = System.getProperty("java.class.path"); final File grinderJar = findFileInPath(classpath, "grinder.jar"); final File grinderJarDirectory = grinderJar != null ? grinderJar.getParentFile() : new File("."); final File jythonJar = findFileInPath(classpath, "jython.jar"); final File jythonHome = jythonJar != null ? jythonJar.getParentFile() : grinderJarDirectory; if (grinderJarDirectory == null && jythonJar == null || grinderJarDirectory != null && grinderJarDirectory.equals(jythonHome)) { final File cacheDir = new File(jythonHome, CACHEDIR_DEFAULT_NAME); System.setProperty("python.cachedir", cacheDir.getAbsolutePath()); } } m_systemState = new PySystemState(); m_interpreter = new PythonInterpreter(null, m_systemState); m_interpreter.exec("class ___DieQuietly___: pass"); m_dieQuietly = (PyClass) m_interpreter.get("___DieQuietly___"); String version; try { version = PySystemState.class.getField("version").get(null).toString(); } catch (final Exception e) { version = "Unknown"; } m_version = version; // Prepend the script directory to the Python path. This matches the // behaviour of the Jython interpreter. m_systemState.path.insert(0, new PyString(script.getFile().getParent())); // Additionally, add the working directory to the Python path. I think // this will always be the same as the worker's CWD. Users expect to be // able to import from the directory the agent is running in or (when the // script has been distributed), the distribution directory. m_systemState.path.insert(1, new PyString(script.getDirectory().getFile().getPath())); try { // Run the test script, script does global set up here. m_interpreter.execfile(script.getFile().getPath()); } catch (final PyException e) { throw new JythonScriptExecutionException("initialising test script", e); } // Find the callable that acts as a factory for test runner instances. m_testRunnerFactory = m_interpreter.get(TEST_RUNNER_CALLABLE_NAME); if (m_testRunnerFactory == null || !m_testRunnerFactory.isCallable()) { throw new JythonScriptExecutionException( "There is no callable (class or function) named '" + TEST_RUNNER_CALLABLE_NAME + "' in " + script); } }