/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.calcnode; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import java.util.Collections; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.testng.annotations.Test; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.engine.ComputationTargetSpecification; import com.opengamma.engine.calcnode.CalculationJobItem; import com.opengamma.engine.calcnode.MaximumJobItemExecutionWatchdog; import com.opengamma.engine.function.EmptyFunctionParameters; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.engine.view.ExecutionLogMode; import com.opengamma.util.test.TestGroup; import com.opengamma.util.test.Timeout; /** * Tests the {@link MaximumJobItemExecutionWatchdogTest}. */ @Test(groups = TestGroup.INTEGRATION) public class MaximumJobItemExecutionWatchdogTest { private final CalculationJobItem JOB = new CalculationJobItem("", new EmptyFunctionParameters(), ComputationTargetSpecification.NULL, Collections.<ValueSpecification>emptySet(), Collections.<ValueSpecification>emptySet(), ExecutionLogMode.INDICATORS); public void testNoAlert() throws Exception { final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); try { final MaximumJobItemExecutionWatchdog watchdog = new MaximumJobItemExecutionWatchdog(); watchdog.setMaxJobItemExecutionTime(Timeout.standardTimeoutMillis() / 2); watchdog.setScheduler(scheduler); final CyclicBarrier barrier = new CyclicBarrier(2); (new Thread() { @Override public void run() { try { barrier.await(Timeout.standardTimeoutMillis(), TimeUnit.MILLISECONDS); barrier.reset(); watchdog.jobExecutionStarted(JOB); watchdog.jobExecutionStopped(); barrier.await(Timeout.standardTimeoutMillis() * 2, TimeUnit.MILLISECONDS); watchdog.jobExecutionStarted(JOB); watchdog.jobExecutionStopped(); } catch (final Exception e) { throw new OpenGammaRuntimeException("exception", e); } } }).start(); barrier.await(Timeout.standardTimeoutMillis(), TimeUnit.MILLISECONDS); Thread.sleep(Timeout.standardTimeoutMillis()); // Watchdog should have run while the thread is alive, but not executing anything assertTrue(watchdog.areThreadsAlive()); barrier.await(Timeout.standardTimeoutMillis(), TimeUnit.MILLISECONDS); Thread.sleep(Timeout.standardTimeoutMillis()); // Watchdog should have run with the thread dead assertFalse(watchdog.areThreadsAlive()); } finally { scheduler.shutdown(); } } public void testAlert() throws Exception { final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); try { final MaximumJobItemExecutionWatchdog watchdog = new MaximumJobItemExecutionWatchdog(); watchdog.setMaxJobItemExecutionTime(Timeout.standardTimeoutMillis() / 2); watchdog.setScheduler(scheduler); final AtomicReference<InterruptedException> caught = new AtomicReference<InterruptedException>(); final CyclicBarrier barrier = new CyclicBarrier(2); (new Thread() { @Override public void run() { try { watchdog.jobExecutionStarted(JOB); barrier.await(Timeout.standardTimeoutMillis(), TimeUnit.MILLISECONDS); Thread.sleep(Timeout.standardTimeoutMillis() * 3); } catch (final InterruptedException e) { caught.set(e); } catch (final Exception e) { throw new OpenGammaRuntimeException("exception", e); } } }).start(); barrier.await(Timeout.standardTimeoutMillis(), TimeUnit.MILLISECONDS); assertTrue(watchdog.areThreadsAlive()); Thread.sleep(Timeout.standardTimeoutMillis()); // Watchdog will have fired and the default action will have interrupted the thread assertFalse(watchdog.areThreadsAlive()); assertNotNull(caught.get()); } finally { scheduler.shutdown(); } } }