You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by zj...@apache.org on 2017/09/03 02:41:22 UTC

[3/9] zeppelin git commit: [ZEPPELIN-2627] Interpreter Component Refactoring

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java
index 1aab757..3c061a9 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java
@@ -1,327 +1,411 @@
-package org.apache.zeppelin.interpreter;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
+package org.apache.zeppelin.interpreter;
 
 import org.junit.Test;
 
-import org.apache.zeppelin.dep.Dependency;
-import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
+import static org.junit.Assert.assertNull;
 
 public class InterpreterSettingTest {
 
   @Test
-  public void sharedModeCloseandRemoveInterpreterGroupTest() {
+  public void testCreateInterpreters() {
     InterpreterOption interpreterOption = new InterpreterOption();
     interpreterOption.setPerUser(InterpreterOption.SHARED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
-
-    // This won't effect anything
-    Interpreter mockInterpreter2 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList2 = new ArrayList<>();
-    interpreterList2.add(mockInterpreter2);
-    interpreterGroup = interpreterSetting.getInterpreterGroup("user2", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user2", "note1"), interpreterList2);
-
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note1").size());
-
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user2");
-    assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
+    interpreterOption.setRemote(false);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create default interpreter for user1 and note1
+    assertEquals(EchoInterpreter.class.getName(), interpreterSetting.getDefaultInterpreter("user1", "note1").getClassName());
+
+    // create interpreter echo for user1 and note1
+    assertEquals(EchoInterpreter.class.getName(), interpreterSetting.getInterpreter("user1", "note1", "echo").getClassName());
+    assertEquals(interpreterSetting.getDefaultInterpreter("user1", "note1"), interpreterSetting.getInterpreter("user1", "note1", "echo"));
+
+    // create interpreter double_echo for user1 and note1
+    assertEquals(DoubleEchoInterpreter.class.getName(), interpreterSetting.getInterpreter("user1", "note1", "double_echo").getClassName());
+
+    // create non-existed interpreter
+    assertNull(interpreterSetting.getInterpreter("user1", "note1", "invalid_echo"));
   }
 
   @Test
-  public void perUserScopedModeCloseAndRemoveInterpreterGroupTest() {
+  public void testSharedMode() {
     InterpreterOption interpreterOption = new InterpreterOption();
-    interpreterOption.setPerUser(InterpreterOption.SCOPED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
-
-    Interpreter mockInterpreter2 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList2 = new ArrayList<>();
-    interpreterList2.add(mockInterpreter2);
-    interpreterGroup = interpreterSetting.getInterpreterGroup("user2", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user2", "note1"), interpreterList2);
+    interpreterOption.setPerUser(InterpreterOption.SHARED);
+    interpreterOption.setRemote(false);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create default interpreter for user1 and note1
+    interpreterSetting.getDefaultInterpreter("user1", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
 
+    // create default interpreter for user2 and note1
+    interpreterSetting.getDefaultInterpreter("user2", "note1");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(2, interpreterSetting.getInterpreterGroup("user1", "note1").size());
-    assertEquals(2, interpreterSetting.getInterpreterGroup("user2", "note1").size());
 
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user1");
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user2","note1").size());
+    // create default interpreter user1 and note2
+    interpreterSetting.getDefaultInterpreter("user1", "note2");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
 
-    // Check if non-existed key works or not
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user1");
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user2","note1").size());
+    // only 1 session is created, this session is shared across users and notes
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user2");
+    interpreterSetting.closeInterpreters("note1", "user1");
     assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
   }
 
   @Test
-  public void perUserIsolatedModeCloseAndRemoveInterpreterGroupTest() {
+  public void testPerUserScopedMode() {
     InterpreterOption interpreterOption = new InterpreterOption();
-    interpreterOption.setPerUser(InterpreterOption.ISOLATED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
-
-    Interpreter mockInterpreter2 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList2 = new ArrayList<>();
-    interpreterList2.add(mockInterpreter2);
-    interpreterGroup = interpreterSetting.getInterpreterGroup("user2", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user2", "note1"), interpreterList2);
+    interpreterOption.setPerUser(InterpreterOption.SCOPED);
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create interpreter for user1 and note1
+    interpreterSetting.getDefaultInterpreter("user1", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
-    assertEquals(2, interpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note1").size());
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user2", "note1").size());
+    // create interpreter for user2 and note1
+    interpreterSetting.getDefaultInterpreter("user2", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user1");
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user2","note1").size());
+    interpreterSetting.closeInterpreters("user1", "note1");
+    // InterpreterGroup is still there, but one session is removed
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user2");
+    interpreterSetting.closeInterpreters("user2", "note1");
     assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
   }
 
   @Test
-  public void perNoteScopedModeCloseAndRemoveInterpreterGroupTest() {
+  public void testPerNoteScopedMode() {
     InterpreterOption interpreterOption = new InterpreterOption();
     interpreterOption.setPerNote(InterpreterOption.SCOPED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
-
-    Interpreter mockInterpreter2 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList2 = new ArrayList<>();
-    interpreterList2.add(mockInterpreter2);
-    interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note2");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note2"), interpreterList2);
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create interpreter for user1 and note1
+    interpreterSetting.getDefaultInterpreter("user1", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
+    // create interpreter for user1 and note2
+    interpreterSetting.getDefaultInterpreter("user1", "note2");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(2, interpreterSetting.getInterpreterGroup("user1", "note1").size());
-    assertEquals(2, interpreterSetting.getInterpreterGroup("user1", "note2").size());
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user1");
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1","note2").size());
+    interpreterSetting.closeInterpreters("user1", "note1");
+    // InterpreterGroup is still there, but one session is removed
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
-    // Check if non-existed key works or not
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user1");
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1","note2").size());
+    interpreterSetting.closeInterpreters("user1", "note2");
+    assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
+  }
 
-    interpreterSetting.closeAndRemoveInterpreterGroup("note2", "user1");
+  @Test
+  public void testPerUserIsolatedMode() {
+    InterpreterOption interpreterOption = new InterpreterOption();
+    interpreterOption.setPerUser(InterpreterOption.ISOLATED);
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create interpreter for user1 and note1
+    interpreterSetting.getDefaultInterpreter("user1", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+
+    // create interpreter for user2 and note1
+    interpreterSetting.getDefaultInterpreter("user2", "note1");
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().size());
+
+    // Each user own one InterpreterGroup and one session per InterpreterGroup
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(1).getSessionNum());
+
+    interpreterSetting.closeInterpreters("user1", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    interpreterSetting.closeInterpreters("user2", "note1");
     assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
   }
 
   @Test
-  public void perNoteIsolatedModeCloseAndRemoveInterpreterGroupTest() {
+  public void testPerNoteIsolatedMode() {
     InterpreterOption interpreterOption = new InterpreterOption();
     interpreterOption.setPerNote(InterpreterOption.ISOLATED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
-
-    Interpreter mockInterpreter2 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList2 = new ArrayList<>();
-    interpreterList2.add(mockInterpreter2);
-    interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note2");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note2"), interpreterList2);
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create interpreter for user1 and note1
+    interpreterSetting.getDefaultInterpreter("user1", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
+    // create interpreter for user2 and note2
+    interpreterSetting.getDefaultInterpreter("user1", "note2");
     assertEquals(2, interpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note1").size());
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note2").size());
+    // Each user own one InterpreterGroup and one session per InterpreterGroup
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(1).getSessionNum());
 
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1", "user1");
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1","note2").size());
+    interpreterSetting.closeInterpreters("user1", "note1");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-
-    interpreterSetting.closeAndRemoveInterpreterGroup("note2", "user1");
+    interpreterSetting.closeInterpreters("user1", "note2");
     assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
   }
 
   @Test
-  public void perNoteScopedModeRemoveInterpreterGroupWhenNoteIsRemoved() {
+  public void testPerUserIsolatedPerNoteScopedMode() {
     InterpreterOption interpreterOption = new InterpreterOption();
+    interpreterOption.setPerUser(InterpreterOption.ISOLATED);
     interpreterOption.setPerNote(InterpreterOption.SCOPED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create interpreter for user1 and note1
+    interpreterSetting.getDefaultInterpreter("user1", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+
+    interpreterSetting.getDefaultInterpreter("user1", "note2");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+
+    // create interpreter for user2 and note1
+    interpreterSetting.getDefaultInterpreter("user2", "note1");
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().size());
+
+    // group1 for user1 has 2 sessions, and group2 for user2 has 1 session
+    assertEquals(interpreterSetting.getInterpreterGroup("user1", "note1"), interpreterSetting.getInterpreterGroup("user1", "note2"));
+    assertEquals(2, interpreterSetting.getInterpreterGroup("user1", "note1").getSessionNum());
+    assertEquals(2, interpreterSetting.getInterpreterGroup("user1", "note2").getSessionNum());
+    assertEquals(1, interpreterSetting.getInterpreterGroup("user2", "note1").getSessionNum());
+
+    // close one session for user1
+    interpreterSetting.closeInterpreters("user1", "note1");
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().size());
+    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note1").getSessionNum());
 
+    // close another session for user1
+    interpreterSetting.closeInterpreters("user1", "note2");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note1").size());
 
-    // This method will be called when remove note
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1","");
+    // close session for user2
+    interpreterSetting.closeInterpreters("user2", "note1");
     assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
-    // Be careful that getInterpreterGroup makes interpreterGroup if it doesn't exist
-    assertEquals(0, interpreterSetting.getInterpreterGroup("user1","note1").size());
   }
 
   @Test
-  public void perNoteIsolatedModeRemoveInterpreterGroupWhenNoteIsRemoved() {
+  public void testPerUserIsolatedPerNoteIsolatedMode() {
     InterpreterOption interpreterOption = new InterpreterOption();
+    interpreterOption.setPerUser(InterpreterOption.ISOLATED);
     interpreterOption.setPerNote(InterpreterOption.ISOLATED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create interpreter for user1 and note1
+    interpreterSetting.getDefaultInterpreter("user1", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
+
+    // create interpreter for user1 and note2
+    interpreterSetting.getDefaultInterpreter("user1", "note2");
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().size());
+
+    // create interpreter for user2 and note1
+    interpreterSetting.getDefaultInterpreter("user2", "note1");
+    assertEquals(3, interpreterSetting.getAllInterpreterGroups().size());
+
+    // create interpreter for user2 and note2
+    interpreterSetting.getDefaultInterpreter("user2", "note2");
+    assertEquals(4, interpreterSetting.getAllInterpreterGroups().size());
+
+    for (InterpreterGroup interpreterGroup : interpreterSetting.getAllInterpreterGroups()) {
+      // each InterpreterGroup has one session
+      assertEquals(1, interpreterGroup.getSessionNum());
+    }
 
+    // close one session for user1 and note1
+    interpreterSetting.closeInterpreters("user1", "note1");
+    assertEquals(3, interpreterSetting.getAllInterpreterGroups().size());
+
+    // close one session for user1 and note2
+    interpreterSetting.closeInterpreters("user1", "note2");
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().size());
+
+    // close one session for user2 and note1
+    interpreterSetting.closeInterpreters("user2", "note1");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note1").size());
 
-    // This method will be called when remove note
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1","");
+    // close one session for user2 and note2
+    interpreterSetting.closeInterpreters("user2", "note2");
     assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
-    // Be careful that getInterpreterGroup makes interpreterGroup if it doesn't exist
-    assertEquals(0, interpreterSetting.getInterpreterGroup("user1","note1").size());
   }
 
   @Test
-  public void perUserScopedModeNeverRemoveInterpreterGroupWhenNoteIsRemoved() {
+  public void testPerUserScopedPerNoteScopedMode() {
     InterpreterOption interpreterOption = new InterpreterOption();
     interpreterOption.setPerUser(InterpreterOption.SCOPED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
-
+    interpreterOption.setPerNote(InterpreterOption.SCOPED);
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, 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)
+        .create();
+
+    // create interpreter for user1 and note1
+    interpreterSetting.getDefaultInterpreter("user1", "note1");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note1").size());
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
-    // This method will be called when remove note
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1","");
+    // create interpreter for user1 and note2
+    interpreterSetting.getDefaultInterpreter("user1", "note2");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-    // Be careful that getInterpreterGroup makes interpreterGroup if it doesn't exist
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1","note1").size());
-  }
-
-  @Test
-  public void perUserIsolatedModeNeverRemoveInterpreterGroupWhenNoteIsRemoved() {
-    InterpreterOption interpreterOption = new InterpreterOption();
-    interpreterOption.setPerUser(InterpreterOption.ISOLATED);
-    InterpreterSetting interpreterSetting = new InterpreterSetting("", "", "", new ArrayList<InterpreterInfo>(), new Properties(), new ArrayList<Dependency>(), interpreterOption, "", null);
-
-    interpreterSetting.setInterpreterGroupFactory(new InterpreterGroupFactory() {
-      @Override
-      public InterpreterGroup createInterpreterGroup(String interpreterGroupId,
-          InterpreterOption option) {
-        return new InterpreterGroup(interpreterGroupId);
-      }
-    });
-
-    Interpreter mockInterpreter1 = mock(RemoteInterpreter.class);
-    List<Interpreter> interpreterList1 = new ArrayList<>();
-    interpreterList1.add(mockInterpreter1);
-    InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup("user1", "note1");
-    interpreterGroup.put(interpreterSetting.getInterpreterSessionKey("user1", "note1"), interpreterList1);
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
+    // create interpreter for user2 and note1
+    interpreterSetting.getDefaultInterpreter("user2", "note1");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1", "note1").size());
+    assertEquals(3, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
 
-    // This method will be called when remove note
-    interpreterSetting.closeAndRemoveInterpreterGroup("note1","");
+    // create interpreter for user2 and note2
+    interpreterSetting.getDefaultInterpreter("user2", "note2");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
-    // Be careful that getInterpreterGroup makes interpreterGroup if it doesn't exist
-    assertEquals(1, interpreterSetting.getInterpreterGroup("user1","note1").size());
+    assertEquals(4, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+
+    // close one session for user1 and note1
+    interpreterSetting.closeInterpreters("user1", "note1");
+    assertEquals(3, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+
+    // close one session for user1 and note2
+    interpreterSetting.closeInterpreters("user1", "note2");
+    assertEquals(2, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+
+    // close one session for user2 and note1
+    interpreterSetting.closeInterpreters("user2", "note1");
+    assertEquals(1, interpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
+
+    // close one session for user2 and note2
+    interpreterSetting.closeInterpreters("user2", "note2");
+    assertEquals(0, interpreterSetting.getAllInterpreterGroups().size());
   }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroupTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroupTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroupTest.java
new file mode 100644
index 0000000..a5d7bd4
--- /dev/null
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroupTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zeppelin.interpreter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonatype.aether.RepositoryException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class ManagedInterpreterGroupTest {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(ManagedInterpreterGroupTest.class);
+
+  private InterpreterSetting interpreterSetting;
+
+  @Before
+  public void setUp() throws IOException, RepositoryException {
+    InterpreterOption interpreterOption = new InterpreterOption();
+    interpreterOption.setPerUser(InterpreterOption.SCOPED);
+    interpreterOption.setRemote(false);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap<String, Object>());
+    InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap<String, Object>());
+    List<InterpreterInfo> interpreterInfos = new ArrayList<>();
+    interpreterInfos.add(interpreterInfo1);
+    interpreterInfos.add(interpreterInfo2);
+    interpreterSetting = new InterpreterSetting.Builder()
+        .setId("id")
+        .setName("test")
+        .setGroup("test")
+        .setInterpreterInfos(interpreterInfos)
+        .setOption(interpreterOption)
+        .create();
+  }
+
+  @Test
+  public void testInterpreterGroup() {
+    ManagedInterpreterGroup interpreterGroup = new ManagedInterpreterGroup("group_1", interpreterSetting);
+    assertEquals(0, interpreterGroup.getSessionNum());
+
+    // create session_1
+    List<Interpreter> interpreters = interpreterGroup.getOrCreateSession("user1", "session_1");
+    assertEquals(2, interpreters.size());
+    assertEquals(EchoInterpreter.class.getName(), interpreters.get(0).getClassName());
+    assertEquals(DoubleEchoInterpreter.class.getName(), interpreters.get(1).getClassName());
+    assertEquals(1, interpreterGroup.getSessionNum());
+
+    // get the same interpreters when interpreterGroup.getOrCreateSession is invoked again
+    assertEquals(interpreters, interpreterGroup.getOrCreateSession("user1", "session_1"));
+    assertEquals(1, interpreterGroup.getSessionNum());
+
+    // create session_2
+    List<Interpreter> interpreters2 = interpreterGroup.getOrCreateSession("user1", "session_2");
+    assertEquals(2, interpreters2.size());
+    assertEquals(EchoInterpreter.class.getName(), interpreters2.get(0).getClassName());
+    assertEquals(DoubleEchoInterpreter.class.getName(), interpreters2.get(1).getClassName());
+    assertEquals(2, interpreterGroup.getSessionNum());
+
+    // close session_1
+    interpreterGroup.close("session_1");
+    assertEquals(1, interpreterGroup.getSessionNum());
+
+    // close InterpreterGroup
+    interpreterGroup.close();
+    assertEquals(0, interpreterGroup.getSessionNum());
+  }
+}

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SleepInterpreter.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SleepInterpreter.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SleepInterpreter.java
new file mode 100644
index 0000000..9deafcf
--- /dev/null
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SleepInterpreter.java
@@ -0,0 +1,60 @@
+package org.apache.zeppelin.interpreter;
+
+import org.apache.zeppelin.scheduler.Scheduler;
+import org.apache.zeppelin.scheduler.SchedulerFactory;
+
+import java.util.Properties;
+
+/**
+ * Interpreter that only accept long value and sleep for such period
+ */
+public class SleepInterpreter extends Interpreter {
+
+  public SleepInterpreter(Properties property) {
+    super(property);
+  }
+
+  @Override
+  public void open() {
+
+  }
+
+  @Override
+  public void close() {
+
+  }
+
+  @Override
+  public InterpreterResult interpret(String st, InterpreterContext context) {
+    try {
+      Thread.sleep(Long.parseLong(st));
+      return new InterpreterResult(InterpreterResult.Code.SUCCESS);
+    } catch (Exception e) {
+      return new InterpreterResult(InterpreterResult.Code.ERROR, e.getMessage());
+    }
+  }
+
+  @Override
+  public void cancel(InterpreterContext context) {
+
+  }
+
+  @Override
+  public FormType getFormType() {
+    return FormType.NATIVE;
+  }
+
+  @Override
+  public Scheduler getScheduler() {
+    if (Boolean.parseBoolean(property.getProperty("zeppelin.SleepInterpreter.parallel", "false"))) {
+      return SchedulerFactory.singleton().createOrGetParallelScheduler(
+          "Parallel-" + SleepInterpreter.class.getName(), 10);
+    }
+    return super.getScheduler();
+  }
+
+  @Override
+  public int getProgress(InterpreterContext context) {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter1.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter1.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter1.java
index b16e937..a533c12 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter1.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter1.java
@@ -17,11 +17,6 @@
 
 package org.apache.zeppelin.interpreter.mock;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
 import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.interpreter.InterpreterContext;
 import org.apache.zeppelin.interpreter.InterpreterResult;
@@ -29,8 +24,14 @@ import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
 import org.apache.zeppelin.scheduler.Scheduler;
 import org.apache.zeppelin.scheduler.SchedulerFactory;
 
-public class MockInterpreter1 extends Interpreter{
-Map<String, Object> vars = new HashMap<>();
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+public class MockInterpreter1 extends Interpreter {
+
+	Map<String, Object> vars = new HashMap<>();
 
 	public MockInterpreter1(Properties property) {
 		super(property);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter11.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter11.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter11.java
deleted file mode 100644
index 5b9e802..0000000
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter11.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.zeppelin.interpreter.mock;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.zeppelin.interpreter.Interpreter;
-import org.apache.zeppelin.interpreter.InterpreterContext;
-import org.apache.zeppelin.interpreter.InterpreterResult;
-import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
-import org.apache.zeppelin.scheduler.Scheduler;
-import org.apache.zeppelin.scheduler.SchedulerFactory;
-
-public class MockInterpreter11 extends Interpreter{
-  Map<String, Object> vars = new HashMap<>();
-
-  public MockInterpreter11(Properties property) {
-    super(property);
-  }
-  boolean open;
-
-  @Override
-  public void open() {
-    open = true;
-  }
-
-  @Override
-  public void close() {
-    open = false;
-  }
-
-  public boolean isOpen() {
-    return open;
-  }
-
-  @Override
-  public InterpreterResult interpret(String st, InterpreterContext context) {
-    return new InterpreterResult(InterpreterResult.Code.SUCCESS, "repl11: "+st);
-  }
-
-  @Override
-  public void cancel(InterpreterContext context) {
-  }
-
-  @Override
-  public FormType getFormType() {
-    return FormType.SIMPLE;
-  }
-
-  @Override
-  public int getProgress(InterpreterContext context) {
-    return 0;
-  }
-
-  @Override
-  public Scheduler getScheduler() {
-    return SchedulerFactory.singleton().createOrGetFIFOScheduler("test_"+this.hashCode());
-  }
-
-  @Override
-  public List<InterpreterCompletion> completion(String buf, int cursor,
-      InterpreterContext interpreterContext) {
-    return null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter2.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter2.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter2.java
index 7a52f7d..f36df56 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter2.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/mock/MockInterpreter2.java
@@ -17,11 +17,6 @@
 
 package org.apache.zeppelin.interpreter.mock;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
 import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.interpreter.InterpreterContext;
 import org.apache.zeppelin.interpreter.InterpreterResult;
@@ -29,6 +24,11 @@ import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
 import org.apache.zeppelin.scheduler.Scheduler;
 import org.apache.zeppelin.scheduler.SchedulerFactory;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
 public class MockInterpreter2 extends Interpreter{
   Map<String, Object> vars = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/AppendOutputRunnerTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/AppendOutputRunnerTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/AppendOutputRunnerTest.java
index c8c64ea..c9dc5c0 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/AppendOutputRunnerTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/AppendOutputRunnerTest.java
@@ -17,23 +17,6 @@
 
 package org.apache.zeppelin.interpreter.remote;
 
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.atMost;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
 import org.apache.log4j.AppenderSkeleton;
 import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
@@ -43,6 +26,19 @@ import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.*;
+
 public class AppendOutputRunnerTest {
 
   private static final int NUM_EVENTS = 10000;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java
index f7404e3..61e4ef0 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java
@@ -17,15 +17,10 @@
 
 package org.apache.zeppelin.interpreter.remote;
 
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Properties;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.zeppelin.display.*;
+import org.apache.zeppelin.display.AngularObject;
+import org.apache.zeppelin.display.AngularObjectRegistry;
+import org.apache.zeppelin.display.AngularObjectRegistryListener;
+import org.apache.zeppelin.display.GUI;
 import org.apache.zeppelin.interpreter.*;
 import org.apache.zeppelin.interpreter.remote.mock.MockInterpreterAngular;
 import org.apache.zeppelin.resource.LocalResourcePool;
@@ -34,17 +29,25 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
 public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
   private static final String INTERPRETER_SCRIPT =
-          System.getProperty("os.name").startsWith("Windows") ?
-                  "../bin/interpreter.cmd" :
-                  "../bin/interpreter.sh";
+      System.getProperty("os.name").startsWith("Windows") ?
+          "../bin/interpreter.cmd" :
+          "../bin/interpreter.sh";
 
-  private InterpreterGroup intpGroup;
-  private HashMap<String, String> env;
   private RemoteInterpreter intp;
   private InterpreterContext context;
   private RemoteAngularObjectRegistry localRegistry;
+  private InterpreterSetting interpreterSetting;
 
   private AtomicInteger onAdd;
   private AtomicInteger onUpdate;
@@ -56,32 +59,24 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
     onUpdate = new AtomicInteger(0);
     onRemove = new AtomicInteger(0);
 
-    intpGroup = new InterpreterGroup("intpId");
-    localRegistry = new RemoteAngularObjectRegistry("intpId", this, intpGroup);
-    intpGroup.setAngularObjectRegistry(localRegistry);
-    env = new HashMap<>();
-    env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath());
-
-    Properties p = new Properties();
-
-    intp = new RemoteInterpreter(
-        p,
-        "note",
-        MockInterpreterAngular.class.getName(),
-        new File(INTERPRETER_SCRIPT).getAbsolutePath(),
-        "fake",
-        "fakeRepo",
-        env,
-        10 * 1000,
-        null,
-        null,
-        "anonymous",
-        false
-    );
-
-    intpGroup.put("note", new LinkedList<Interpreter>());
-    intpGroup.get("note").add(intp);
-    intp.setInterpreterGroup(intpGroup);
+    InterpreterOption interpreterOption = new InterpreterOption();
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(MockInterpreterAngular.class.getName(), "mock", true, new HashMap<String, Object>());
+    List<InterpreterInfo> interpreterInfos = new ArrayList<>();
+    interpreterInfos.add(interpreterInfo1);
+    InterpreterRunner runner = new InterpreterRunner(INTERPRETER_SCRIPT, INTERPRETER_SCRIPT);
+    interpreterSetting = new InterpreterSetting.Builder()
+        .setId("test")
+        .setName("test")
+        .setGroup("test")
+        .setInterpreterInfos(interpreterInfos)
+        .setOption(interpreterOption)
+        .setRunner(runner)
+        .setInterpreterDir("../interpeters/test")
+        .create();
+
+    intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
+    localRegistry = (RemoteAngularObjectRegistry) intp.getInterpreterGroup().getAngularObjectRegistry();
 
     context = new InterpreterContext(
         "note",
@@ -92,17 +87,17 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
         new AuthenticationInfo(),
         new HashMap<String, Object>(),
         new GUI(),
-        new AngularObjectRegistry(intpGroup.getId(), null),
+        new AngularObjectRegistry(intp.getInterpreterGroup().getId(), null),
         new LocalResourcePool("pool1"),
         new LinkedList<InterpreterContextRunner>(), null);
 
     intp.open();
+
   }
 
   @After
   public void tearDown() throws Exception {
-    intp.close();
-    intpGroup.close();
+    interpreterSetting.close();
   }
 
   @Test
@@ -147,7 +142,7 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
     Thread.sleep(500); // waitFor eventpoller pool event
     String[] result = ret.message().get(0).getData().split(" ");
     assertEquals("0", result[0]); // size of registry
-    
+
     // create object
     ret = intp.interpret("add n1 v1", context);
     Thread.sleep(500);
@@ -172,11 +167,11 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
     Thread.sleep(500); // waitFor eventpoller pool event
     String[] result = ret.message().get(0).getData().split(" ");
     assertEquals("0", result[0]); // size of registry
-    
+
     // create object
     localRegistry.addAndNotifyRemoteProcess("n1", "v1", "note", null);
-    
-    // get from remote registry 
+
+    // get from remote registry
     ret = intp.interpret("get", context);
     Thread.sleep(500); // waitFor eventpoller pool event
     result = ret.message().get(0).getData().split(" ");

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
index 3f865cb..1687060 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
@@ -17,22 +17,18 @@
 
 package org.apache.zeppelin.interpreter.remote;
 
-import org.apache.zeppelin.display.AngularObjectRegistry;
-import org.apache.zeppelin.user.AuthenticationInfo;
 import org.apache.zeppelin.display.GUI;
 import org.apache.zeppelin.interpreter.*;
 import org.apache.zeppelin.interpreter.remote.mock.MockInterpreterOutputStream;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.io.File;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
 
 
 /**
@@ -43,41 +39,32 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
           System.getProperty("os.name").startsWith("Windows") ?
                   "../bin/interpreter.cmd" :
                   "../bin/interpreter.sh";
-  private InterpreterGroup intpGroup;
-  private HashMap<String, String> env;
+
+  private InterpreterSetting interpreterSetting;
 
   @Before
   public void setUp() throws Exception {
-    intpGroup = new InterpreterGroup();
-    intpGroup.put("note", new LinkedList<Interpreter>());
-
-    env = new HashMap<>();
-    env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath());
+    InterpreterOption interpreterOption = new InterpreterOption();
+
+    interpreterOption.setRemote(true);
+    InterpreterInfo interpreterInfo1 = new InterpreterInfo(MockInterpreterOutputStream.class.getName(), "mock", true, new HashMap<String, Object>());
+    List<InterpreterInfo> interpreterInfos = new ArrayList<>();
+    interpreterInfos.add(interpreterInfo1);
+    InterpreterRunner runner = new InterpreterRunner(INTERPRETER_SCRIPT, INTERPRETER_SCRIPT);
+    interpreterSetting = new InterpreterSetting.Builder()
+        .setId("test")
+        .setName("test")
+        .setGroup("test")
+        .setInterpreterInfos(interpreterInfos)
+        .setOption(interpreterOption)
+        .setRunner(runner)
+        .setInterpreterDir("../interpeters/test")
+        .create();
   }
 
   @After
   public void tearDown() throws Exception {
-    intpGroup.close();
-  }
-
-  private RemoteInterpreter createMockInterpreter() {
-    RemoteInterpreter intp = new RemoteInterpreter(
-        new Properties(),
-        "note",
-        MockInterpreterOutputStream.class.getName(),
-        new File(INTERPRETER_SCRIPT).getAbsolutePath(),
-        "fake",
-        "fakeRepo",
-        env,
-        10 * 1000,
-        this,
-        null,
-        "anonymous",
-        false);
-
-    intpGroup.get("note").add(intp);
-    intp.setInterpreterGroup(intpGroup);
-    return intp;
+    interpreterSetting.close();
   }
 
   private InterpreterContext createInterpreterContext() {
@@ -90,14 +77,14 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
         new AuthenticationInfo(),
         new HashMap<String, Object>(),
         new GUI(),
-        new AngularObjectRegistry(intpGroup.getId(), null),
+        null,
         null,
         new LinkedList<InterpreterContextRunner>(), null);
   }
 
   @Test
   public void testInterpreterResultOnly() {
-    RemoteInterpreter intp = createMockInterpreter();
+    RemoteInterpreter intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
     InterpreterResult ret = intp.interpret("SUCCESS::staticresult", createInterpreterContext());
     assertEquals(InterpreterResult.Code.SUCCESS, ret.code());
     assertEquals("staticresult", ret.message().get(0).getData());
@@ -113,7 +100,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
 
   @Test
   public void testInterpreterOutputStreamOnly() {
-    RemoteInterpreter intp = createMockInterpreter();
+    RemoteInterpreter intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
     InterpreterResult ret = intp.interpret("SUCCESS:streamresult:", createInterpreterContext());
     assertEquals(InterpreterResult.Code.SUCCESS, ret.code());
     assertEquals("streamresult", ret.message().get(0).getData());
@@ -125,7 +112,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
 
   @Test
   public void testInterpreterResultOutputStreamMixed() {
-    RemoteInterpreter intp = createMockInterpreter();
+    RemoteInterpreter intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
     InterpreterResult ret = intp.interpret("SUCCESS:stream:static", createInterpreterContext());
     assertEquals(InterpreterResult.Code.SUCCESS, ret.code());
     assertEquals("stream", ret.message().get(0).getData());
@@ -134,7 +121,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
 
   @Test
   public void testOutputType() {
-    RemoteInterpreter intp = createMockInterpreter();
+    RemoteInterpreter intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
 
     InterpreterResult ret = intp.interpret("SUCCESS:%html hello:", createInterpreterContext());
     assertEquals(InterpreterResult.Type.HTML, ret.message().get(0).getType());

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d6203c51/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessTest.java
deleted file mode 100644
index b85d7ef..0000000
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.zeppelin.interpreter.remote;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.Mockito.*;
-
-import java.util.HashMap;
-import java.util.Properties;
-
-import org.apache.thrift.TException;
-import org.apache.thrift.transport.TTransportException;
-import org.apache.zeppelin.interpreter.Constants;
-import org.apache.zeppelin.interpreter.InterpreterException;
-import org.apache.zeppelin.interpreter.InterpreterGroup;
-import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService.Client;
-import org.junit.Test;
-
-public class RemoteInterpreterProcessTest {
-  private static final String INTERPRETER_SCRIPT =
-          System.getProperty("os.name").startsWith("Windows") ?
-                  "../bin/interpreter.cmd" :
-                  "../bin/interpreter.sh";
-  private static final int DUMMY_PORT=3678;
-
-  @Test
-  public void testStartStop() {
-    InterpreterGroup intpGroup = new InterpreterGroup();
-    RemoteInterpreterManagedProcess rip = new RemoteInterpreterManagedProcess(
-        INTERPRETER_SCRIPT, "nonexists", "fakeRepo", new HashMap<String, String>(),
-        10 * 1000, null, null,"fakeName");
-    assertFalse(rip.isRunning());
-    assertEquals(0, rip.referenceCount());
-    assertEquals(1, rip.reference(intpGroup, "anonymous", false));
-    assertEquals(2, rip.reference(intpGroup, "anonymous", false));
-    assertEquals(true, rip.isRunning());
-    assertEquals(1, rip.dereference());
-    assertEquals(true, rip.isRunning());
-    assertEquals(0, rip.dereference());
-    assertEquals(false, rip.isRunning());
-  }
-
-  @Test
-  public void testClientFactory() throws Exception {
-    InterpreterGroup intpGroup = new InterpreterGroup();
-    RemoteInterpreterManagedProcess rip = new RemoteInterpreterManagedProcess(
-        INTERPRETER_SCRIPT, "nonexists", "fakeRepo", new HashMap<String, String>(),
-        mock(RemoteInterpreterEventPoller.class), 10 * 1000, "fakeName");
-    rip.reference(intpGroup, "anonymous", false);
-    assertEquals(0, rip.getNumActiveClient());
-    assertEquals(0, rip.getNumIdleClient());
-
-    Client client = rip.getClient();
-    assertEquals(1, rip.getNumActiveClient());
-    assertEquals(0, rip.getNumIdleClient());
-
-    rip.releaseClient(client);
-    assertEquals(0, rip.getNumActiveClient());
-    assertEquals(1, rip.getNumIdleClient());
-
-    rip.dereference();
-  }
-
-  @Test
-  public void testStartStopRemoteInterpreter() throws TException, InterruptedException {
-    RemoteInterpreterServer server = new RemoteInterpreterServer(3678);
-    server.start();
-    boolean running = false;
-    long startTime = System.currentTimeMillis();
-    while (System.currentTimeMillis() - startTime < 10 * 1000) {
-      if (server.isRunning()) {
-        running = true;
-        break;
-      } else {
-        Thread.sleep(200);
-      }
-    }
-    Properties properties = new Properties();
-    properties.setProperty(Constants.ZEPPELIN_INTERPRETER_PORT, "3678");
-    properties.setProperty(Constants.ZEPPELIN_INTERPRETER_HOST, "localhost");
-    InterpreterGroup intpGroup = mock(InterpreterGroup.class);
-    when(intpGroup.getProperty()).thenReturn(properties);
-    when(intpGroup.containsKey(Constants.EXISTING_PROCESS)).thenReturn(true);
-
-    RemoteInterpreterProcess rip = new RemoteInterpreterManagedProcess(
-        INTERPRETER_SCRIPT,
-        "nonexists",
-        "fakeRepo",
-        new HashMap<String, String>(),
-        mock(RemoteInterpreterEventPoller.class)
-        , 10 * 1000,
-        "fakeName");
-    assertFalse(rip.isRunning());
-    assertEquals(0, rip.referenceCount());
-    assertEquals(1, rip.reference(intpGroup, "anonymous", false));
-    assertEquals(true, rip.isRunning());
-  }
-
-
-  @Test
-  public void testPropagateError() throws TException, InterruptedException {
-    InterpreterGroup intpGroup = new InterpreterGroup();
-    RemoteInterpreterManagedProcess rip = new RemoteInterpreterManagedProcess(
-        "echo hello_world", "nonexists", "fakeRepo", new HashMap<String, String>(),
-        10 * 1000, null, null, "fakeName");
-    assertFalse(rip.isRunning());
-    assertEquals(0, rip.referenceCount());
-    try {
-      assertEquals(1, rip.reference(intpGroup, "anonymous", false));
-    } catch (InterpreterException e) {
-      e.getMessage().contains("hello_world");
-    }
-    assertEquals(0, rip.referenceCount());
-  }
-}