/**
* Copyright 2016 Nabarun Mondal
* Licensed 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 com.noga.njexl.lang;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Tests around asynchronous script execution and interrupts.
*/
public class ScriptCallableTest extends JexlTestCase {
//Logger LOGGER = Logger.getLogger(VarTest.class.getName());
public void testFuture() throws Exception {
Script e = JEXL.createScript("while(true);");
FutureTask<Object> future = new FutureTask<Object>(e.callable(null));
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(future);
try {
future.get(100, TimeUnit.MILLISECONDS);
fail("should have timed out");
} catch (TimeoutException xtimeout) {
// ok, ignore
}
Thread.sleep(100);
future.cancel(true);
assertTrue(future.isCancelled());
}
public void testCallable() throws Exception {
Script e = JEXL.createScript("while(true);");
Callable<Object> c = e.callable(null);
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<?> future = executor.submit(c);
try {
future.get(100, TimeUnit.MILLISECONDS);
fail("should have timed out");
} catch (TimeoutException xtimeout) {
// ok, ignore
}
future.cancel(true);
assertTrue(future.isCancelled());
}
public static class TestContext extends MapContext implements NamespaceResolver {
public Object resolveNamespace(String name) {
return name == null ? this : null;
}
public int wait(int s) throws InterruptedException {
Thread.sleep(1000 * s);
return s;
}
public int waitInterrupt(int s) {
try {
Thread.sleep(1000 * s);
return s;
} catch(InterruptedException xint) {
Thread.currentThread().interrupt();
}
return -1;
}
public int runForever() {
boolean x = false;
while(true) {
if (x) {
break;
}
}
return 1;
}
}
public void testNoWait() throws Exception {
Script e = JEXL.createScript("wait(0)");
Callable<Object> c = e.callable(new TestContext());
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<?> future = executor.submit(c);
Object t = future.get(2, TimeUnit.SECONDS);
assertTrue(future.isDone());
assertEquals(0, t);
}
public void testWait() throws Exception {
Script e = JEXL.createScript("wait(1)");
Callable<Object> c = e.callable(new TestContext());
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<?> future = executor.submit(c);
Object t = future.get(2, TimeUnit.SECONDS);
assertEquals(1, t);
}
public void testCancelWait() throws Exception {
Script e = JEXL.createScript("wait(10)");
Callable<Object> c = e.callable(new TestContext());
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<?> future = executor.submit(c);
try {
future.get(100, TimeUnit.MILLISECONDS);
fail("should have timed out");
} catch (TimeoutException xtimeout) {
// ok, ignore
}
future.cancel(true);
assertTrue(future.isCancelled());
}
public void testCancelWaitInterrupt() throws Exception {
Script e = JEXL.createScript("waitInterrupt(42)");
Callable<Object> c = e.callable(new TestContext());
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<?> future = executor.submit(c);
try {
future.get(100, TimeUnit.MILLISECONDS);
fail("should have timed out");
} catch (TimeoutException xtimeout) {
// ok, ignore
}
future.cancel(true);
assertTrue(future.isCancelled());
}
public void testCancelForever() throws Exception {
Script e = JEXL.createScript("runForever()");
Callable<Object> c = e.callable(new TestContext());
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<?> future = executor.submit(c);
try {
future.get(100, TimeUnit.MILLISECONDS);
fail("should have timed out");
} catch (TimeoutException xtimeout) {
// ok, ignore
}
future.cancel(true);
assertTrue(future.isCancelled());
}
public void testCancelLoopWait() throws Exception {
Script e = JEXL.createScript("while (true) { wait(10) }");
Callable<Object> c = e.callable(new TestContext());
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<?> future = executor.submit(c);
try {
future.get(100, TimeUnit.MILLISECONDS);
fail("should have timed out");
} catch (TimeoutException xtimeout) {
// ok, ignore
}
future.cancel(true);
assertTrue(future.isCancelled());
}
}