/** * 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()); } }