package com.tacitknowledge.slowlight.embedded;
import com.tacitknowledge.slowlight.embedded.stubs.StubbedServiceImpl;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* User: witherspore
* Date: 9/3/13
* Time: 11:42 AM
*/
@RunWith(MockitoJUnitRunner.class)
public class DegradationCallableTest {
@Mock
private DegradationStrategy degradationStrategy;
@Mock
private DegradationHandler degradationHandler;
@Mock
private DegradationPlan degradationPlan;
@Mock
private ThreadLocalUtil threadLocalUtil;
@Before
public void setup()
{
when(degradationStrategy.generateDegradationPlan(degradationHandler)).thenReturn(degradationPlan);
}
@Test
public void testFastFailure() throws Exception {
final StubbedServiceImpl target = new StubbedServiceImpl();
when(degradationPlan.getFastFail()).thenReturn(FastFail.TRUE);
when(degradationPlan.hasPlannedFailure()).thenReturn(Boolean.TRUE);
when(degradationPlan.fail()).thenReturn(1);
DegradationCallable callable = new DegradationCallable(new TargetCallback()
{
@Override
public Object execute() throws Exception
{
return target.callService();
}
}, degradationStrategy, degradationHandler);
Assert.assertEquals(1, callable.call());
verify(degradationPlan).getFastFail();
verify(degradationPlan).hasPlannedFailure();
verify(degradationPlan).fail();
verify(degradationPlan,never()).getDelay();
}
@Test
public void testDelayedFailure() throws Exception {
final StubbedServiceImpl target = new StubbedServiceImpl();
when(degradationPlan.getFastFail()).thenReturn(FastFail.FALSE);
when(degradationPlan.hasPlannedFailure()).thenReturn(Boolean.TRUE);
when(degradationPlan.fail()).thenReturn(1);
DegradationCallable callable = new DegradationCallable(new TargetCallback()
{
@Override
public Object execute() throws Exception
{
return target.callService();
}
}, degradationStrategy, degradationHandler);
Assert.assertEquals(1, callable.call());
verify(degradationPlan).getFastFail();
verify(degradationPlan).hasPlannedFailure();
verify(degradationPlan).fail();
verify(degradationPlan).getDelay();
}
@Test
public void testDelayWithNoFailure() throws Exception {
final StubbedServiceImpl target = new StubbedServiceImpl();
when(degradationStrategy.overrideResult(Matchers.<TargetCallback>any())).thenReturn(target.callService());
when(degradationPlan.getDelay()).thenReturn(0L);
when(degradationPlan.getFastFail()).thenReturn(FastFail.FALSE);
when(degradationPlan.hasPlannedFailure()).thenReturn(Boolean.FALSE);
DegradationCallable callable = new DegradationCallable(new TargetCallback()
{
@Override
public Object execute() throws Exception
{
return target.callService();
}
}, degradationStrategy, degradationHandler);
Assert.assertEquals(0, callable.call());
verify(degradationPlan).getFastFail();
verify(degradationPlan).hasPlannedFailure();
verify(degradationPlan,never()).fail();
verify(degradationPlan).getDelay();
}
@Test
public void callableShouldPropagateThreadLocalsBeforeGeneratingDegradationPlan() throws Exception
{
final DegradationCallable callable = new DegradationCallable(new TargetCallback()
{
@Override
public Object execute() throws Exception
{
return null;
}
}, degradationStrategy, degradationHandler);
callable.setThreadLocalUtil(threadLocalUtil);
callable.call();
final InOrder inOrder = inOrder(threadLocalUtil, degradationStrategy);
inOrder.verify(threadLocalUtil).propagateThreadLocals(Thread.currentThread());
inOrder.verify(degradationStrategy).generateDegradationPlan(degradationHandler);
}
}