List<Interpreter> createInterpreters(String user, String interpreterGroupId, String sessionId) {
    List<Interpreter> interpreters = new ArrayList<>();
    List<InterpreterInfo> interpreterInfos = getInterpreterInfos();
    Properties intpProperties = getJavaProperties();
    for (InterpreterInfo info : interpreterInfos) {
      Interpreter interpreter = new RemoteInterpreter(intpProperties, sessionId,
          info.getClassName(), user, zConf);
      if (info.isDefaultInterpreter()) {
        interpreters.add(0, interpreter);
      } else {
        interpreters.add(interpreter);
      }
      LOGGER.info("Interpreter {} created for user: {}, sessionId: {}",
          interpreter.getClassName(), user, sessionId);
    }

    // TODO(zjffdu) this kind of hardcode is ugly. For now SessionConfInterpreter is used
    // for livy, we could add new property in interpreter-setting.json when there's new interpreter
    // require SessionConfInterpreter
    if (group.equals("livy")) {
      interpreters.add(
          new SessionConfInterpreter(intpProperties, sessionId, interpreterGroupId, this));
    } else {
      interpreters.add(new ConfInterpreter(intpProperties, sessionId, interpreterGroupId, this));
    }
    return interpreters;
  }
@Test
  void testCreateInterpreters() {
    InterpreterOption interpreterOption = new InterpreterOption();
    interpreterOption.setPerUser(InterpreterOption.SHARED);
    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(),
        "echo", true, new HashMap<String, Object>(), new HashMap<String, Object>());
    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(),
        "double_echo", false, new HashMap<String, Object>(),
        new HashMap<String, Object>());
    List<InterpreterInfo> interpreterInfos = new ArrayList<>();
    interpreterInfos.add(interpreterInfo1);
    interpreterInfos.add(interpreterInfo2);

    InterpreterSetting interpreterSetting = new InterpreterSetting.Builder()
        .setId("id")
        .setName("test")
        .setGroup("test")
        .setInterpreterInfos(interpreterInfos)
        .setOption(interpreterOption)
        .setIntepreterSettingManager(interpreterSettingManager)
        .setConf(zConf)
        .create();

    // create default interpreter for user1 and note1
    assertEquals(EchoInterpreter.class.getName(), interpreterSetting.getDefaultInterpreter("user1", note1Id).getClassName());

    // create interpreter echo for user1 and note1
    assertEquals(EchoInterpreter.class.getName(), interpreterSetting.getInterpreter("user1", note1Id, "echo").getClassName());
    assertEquals(interpreterSetting.getDefaultInterpreter("user1", note1Id), interpreterSetting.getInterpreter("user1", note1Id, "echo"));

    // create interpreter double_echo for user1 and note1
    assertEquals(DoubleEchoInterpreter.class.getName(), interpreterSetting.getInterpreter("user1", note1Id, "double_echo").getClassName());

    // create non-existed interpreter
    assertNull(interpreterSetting.getInterpreter("user1", note1Id, "invalid_echo"));
  }