@Override
  public InterpreterResult interpret(String script, InterpreterContext context) {
    LOGGER.debug("Run MongoDB script: {}", script);

    if (StringUtils.isEmpty(script)) {
      return new InterpreterResult(Code.SUCCESS);
    }

    String paragraphId = context.getParagraphId();
    // Write script in a temporary file
    // The script is enriched with extensions
    final File scriptFile = new File(getScriptFileName(paragraphId));
    try {
      FileUtils.write(scriptFile, shellExtension + script);
    }
    catch (IOException e) {
      LOGGER.error("Can not write script in temp file", e);
      return new InterpreterResult(Code.ERROR, e.getMessage());
    }

    InterpreterResult result = new InterpreterResult(InterpreterResult.Code.SUCCESS);

    final DefaultExecutor executor = new DefaultExecutor();
    final ByteArrayOutputStream errorStream = new ByteArrayOutputStream();

    executor.setStreamHandler(new PumpStreamHandler(context.out, errorStream));
    executor.setWatchdog(new ExecuteWatchdog(commandTimeout));

    final CommandLine cmdLine = CommandLine.parse(getProperty("mongo.shell.path"));
    cmdLine.addArgument("--quiet", false);
    cmdLine.addArgument(dbAddress, false);
    cmdLine.addArgument(scriptFile.getAbsolutePath(), false);

    try {
      executor.execute(cmdLine);
      runningProcesses.put(paragraphId, executor);
    }
    catch (ExecuteException e) {
      LOGGER.error("Can not run script in paragraph {}", paragraphId, e);

      final int exitValue = e.getExitValue();
      Code code = Code.ERROR;
      String msg = errorStream.toString();

      if (exitValue == SIGTERM_CODE) {
        code = Code.INCOMPLETE;
        msg = msg + "Paragraph received a SIGTERM.\n";
        LOGGER.info("The paragraph {} stopped executing: {}", paragraphId, msg);
      }

      msg += "ExitValue: " + exitValue;
      result = new InterpreterResult(code, msg);
    }
    catch (IOException e) {
      LOGGER.error("Can not run script in paragraph {}", paragraphId, e);
      result = new InterpreterResult(Code.ERROR, e.getMessage());
    }
    finally {
      FileUtils.deleteQuietly(scriptFile);
      stopProcess(paragraphId);
    }
    return result;
  }
@Test
  void testSuccess() {
    final String userScript = "print('hello');";

    final InterpreterResult res = interpreter.interpret(userScript, context);

    assertSame(Code.SUCCESS, res.code(), "Check SUCCESS: " + res.message());

    try {
      out.flush();
    } catch (IOException ex) {
      System.out.println(ex.getMessage());
    }

    final String resultScript = new String(getBufferBytes());

    final String expectedScript = SHELL_EXTENSION.replace(
        "TABLE_LIMIT_PLACEHOLDER", interpreter.getProperty("mongo.shell.command.table.limit"))
            .replace("TARGET_DB_PLACEHOLDER", interpreter.getProperty("mongo.server.database"))
            .replace("USER_NAME_PLACEHOLDER", interpreter.getProperty("mongo.server.username"))
            .replace("PASSWORD_PLACEHOLDER", interpreter.getProperty("mongo.server.password"))
            .replace("AUTH_DB_PLACEHOLDER", interpreter. getProperty("mongo.server.authenticationDatabase"))+
        userScript;

    // The script that is executed must contain the functions provided by this interpreter
    assertEquals(expectedScript, resultScript, "Check SCRIPT");
  }