/*
* 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 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.interpreter.*;
import org.apache.zeppelin.interpreter.remote.mock.MockInterpreterAngular;
import org.apache.zeppelin.resource.LocalResourcePool;
import org.apache.zeppelin.user.AuthenticationInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
private static final String INTERPRETER_SCRIPT =
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 AtomicInteger onAdd;
private AtomicInteger onUpdate;
private AtomicInteger onRemove;
@Before
public void setUp() throws Exception {
onAdd = new AtomicInteger(0);
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);
context = new InterpreterContext(
"note",
"id",
null,
"title",
"text",
new AuthenticationInfo(),
new HashMap<String, Object>(),
new GUI(),
new AngularObjectRegistry(intpGroup.getId(), null),
new LocalResourcePool("pool1"),
new LinkedList<InterpreterContextRunner>(), null);
intp.open();
}
@After
public void tearDown() throws Exception {
intp.close();
intpGroup.close();
}
@Test
public void testAngularObjectInterpreterSideCRUD() throws InterruptedException {
InterpreterResult ret = intp.interpret("get", context);
Thread.sleep(500); // waitFor eventpoller pool event
String[] result = ret.message().get(0).getData().split(" ");
assertEquals("0", result[0]); // size of registry
assertEquals("0", result[1]); // num watcher called
// create object
ret = intp.interpret("add n1 v1", context);
Thread.sleep(500);
result = ret.message().get(0).getData().split(" ");
assertEquals("1", result[0]); // size of registry
assertEquals("0", result[1]); // num watcher called
assertEquals("v1", localRegistry.get("n1", "note", null).get());
// update object
ret = intp.interpret("update n1 v11", context);
result = ret.message().get(0).getData().split(" ");
Thread.sleep(500);
assertEquals("1", result[0]); // size of registry
assertEquals("1", result[1]); // num watcher called
assertEquals("v11", localRegistry.get("n1", "note", null).get());
// remove object
ret = intp.interpret("remove n1", context);
result = ret.message().get(0).getData().split(" ");
Thread.sleep(500);
assertEquals("0", result[0]); // size of registry
assertEquals("1", result[1]); // num watcher called
assertEquals(null, localRegistry.get("n1", "note", null));
}
@Test
public void testAngularObjectRemovalOnZeppelinServerSide() throws InterruptedException {
// test if angularobject removal from server side propagate to interpreter process's registry.
// will happen when notebook is removed.
InterpreterResult ret = intp.interpret("get", context);
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);
result = ret.message().get(0).getData().split(" ");
assertEquals("1", result[0]); // size of registry
assertEquals("v1", localRegistry.get("n1", "note", null).get());
// remove object in local registry.
localRegistry.removeAndNotifyRemoteProcess("n1", "note", null);
ret = intp.interpret("get", context);
Thread.sleep(500); // waitFor eventpoller pool event
result = ret.message().get(0).getData().split(" ");
assertEquals("0", result[0]); // size of registry
}
@Test
public void testAngularObjectAddOnZeppelinServerSide() throws InterruptedException {
// test if angularobject add from server side propagate to interpreter process's registry.
// will happen when zeppelin server loads notebook and restore the object into registry
InterpreterResult ret = intp.interpret("get", context);
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
ret = intp.interpret("get", context);
Thread.sleep(500); // waitFor eventpoller pool event
result = ret.message().get(0).getData().split(" ");
assertEquals("1", result[0]); // size of registry
}
@Override
public void onAdd(String interpreterGroupId, AngularObject object) {
onAdd.incrementAndGet();
}
@Override
public void onUpdate(String interpreterGroupId, AngularObject object) {
onUpdate.incrementAndGet();
}
@Override
public void onRemove(String interpreterGroupId, String name, String noteId, String paragraphId) {
onRemove.incrementAndGet();
}
}