use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testRequestCacheOnTimeoutThrowsException.
@Test
public void testRequestCacheOnTimeoutThrowsException() throws Exception {
TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
RequestCacheTimeoutWithoutFallback r1 = new RequestCacheTimeoutWithoutFallback(circuitBreaker);
try {
System.out.println("r1 value: " + r1.observe().toBlocking().single());
// we should have thrown an exception
fail("expected a timeout");
} catch (HystrixRuntimeException e) {
assertTrue(r1.isResponseTimedOut());
assertNotNull(r1.getExecutionException());
// what we want
}
RequestCacheTimeoutWithoutFallback r2 = new RequestCacheTimeoutWithoutFallback(circuitBreaker);
try {
r2.observe().toBlocking().single();
// we should have thrown an exception
fail("expected a timeout");
} catch (HystrixRuntimeException e) {
assertTrue(r2.isResponseTimedOut());
assertNotNull(r2.getExecutionException());
// what we want
}
RequestCacheTimeoutWithoutFallback r3 = new RequestCacheTimeoutWithoutFallback(circuitBreaker);
Future<Boolean> f3 = r3.observe().toBlocking().toFuture();
try {
f3.get();
// we should have thrown an exception
fail("expected a timeout");
} catch (ExecutionException e) {
e.printStackTrace();
assertTrue(r3.isResponseTimedOut());
assertNotNull(r3.getExecutionException());
// what we want
}
// timeout on command is set to 200ms
Thread.sleep(500);
RequestCacheTimeoutWithoutFallback r4 = new RequestCacheTimeoutWithoutFallback(circuitBreaker);
try {
r4.observe().toBlocking().single();
// we should have thrown an exception
fail("expected a timeout");
} catch (HystrixRuntimeException e) {
assertTrue(r4.isResponseTimedOut());
assertFalse(r4.isResponseFromFallback());
assertNotNull(r4.getExecutionException());
}
assertCommandExecutionEvents(r1, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING);
assertCommandExecutionEvents(r2, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING, HystrixEventType.RESPONSE_FROM_CACHE);
assertCommandExecutionEvents(r3, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING, HystrixEventType.RESPONSE_FROM_CACHE);
assertCommandExecutionEvents(r4, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING, HystrixEventType.RESPONSE_FROM_CACHE);
assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
assertSaneHystrixRequestLog(4);
}
use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testCircuitBreakerTripsAfterFailures.
/**
* Test that the circuit-breaker will 'trip' and prevent command execution on subsequent calls.
*/
@Test
public void testCircuitBreakerTripsAfterFailures() throws InterruptedException {
HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("KnownFailureTestCommandWithFallback");
TestCircuitBreaker circuitBreaker = new TestCircuitBreaker(commandKey);
/* fail 3 times and then it should trip the circuit and stop executing */
// failure 1
KnownFailureTestCommandWithFallback attempt1 = new KnownFailureTestCommandWithFallback(circuitBreaker, ExecutionIsolationStrategy.SEMAPHORE, true);
attempt1.observe().toBlocking().single();
Thread.sleep(100);
assertTrue(attempt1.isResponseFromFallback());
assertFalse(attempt1.isCircuitBreakerOpen());
assertFalse(attempt1.isResponseShortCircuited());
// failure 2
KnownFailureTestCommandWithFallback attempt2 = new KnownFailureTestCommandWithFallback(circuitBreaker, ExecutionIsolationStrategy.SEMAPHORE, true);
attempt2.observe().toBlocking().single();
Thread.sleep(100);
assertTrue(attempt2.isResponseFromFallback());
assertFalse(attempt2.isCircuitBreakerOpen());
assertFalse(attempt2.isResponseShortCircuited());
// failure 3
KnownFailureTestCommandWithFallback attempt3 = new KnownFailureTestCommandWithFallback(circuitBreaker, ExecutionIsolationStrategy.SEMAPHORE, true);
attempt3.observe().toBlocking().single();
Thread.sleep(100);
assertTrue(attempt3.isResponseFromFallback());
assertFalse(attempt3.isResponseShortCircuited());
// it should now be 'open' and prevent further executions
assertTrue(attempt3.isCircuitBreakerOpen());
// attempt 4
KnownFailureTestCommandWithFallback attempt4 = new KnownFailureTestCommandWithFallback(circuitBreaker, ExecutionIsolationStrategy.SEMAPHORE, true);
attempt4.observe().toBlocking().single();
Thread.sleep(100);
assertTrue(attempt4.isResponseFromFallback());
// this should now be true as the response will be short-circuited
assertTrue(attempt4.isResponseShortCircuited());
// this should remain open
assertTrue(attempt4.isCircuitBreakerOpen());
assertCommandExecutionEvents(attempt1, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_EMIT, HystrixEventType.FALLBACK_SUCCESS);
assertCommandExecutionEvents(attempt2, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_EMIT, HystrixEventType.FALLBACK_SUCCESS);
assertCommandExecutionEvents(attempt3, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_EMIT, HystrixEventType.FALLBACK_SUCCESS);
assertCommandExecutionEvents(attempt4, HystrixEventType.SHORT_CIRCUITED, HystrixEventType.FALLBACK_EMIT, HystrixEventType.FALLBACK_SUCCESS);
assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
assertEquals(4, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
}
use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testRequestContextOnBadFailure.
private RequestContextTestResults testRequestContextOnBadFailure(ExecutionIsolationStrategy isolation, final Scheduler userScheduler) {
final RequestContextTestResults results = new RequestContextTestResults();
TestHystrixObservableCommand<Boolean> command = new TestHystrixObservableCommand<Boolean>(TestHystrixObservableCommand.testPropsBuilder(new TestCircuitBreaker()).setCommandPropertiesDefaults(HystrixCommandPropertiesTest.getUnitTestPropertiesSetter().withExecutionIsolationStrategy(isolation))) {
@Override
protected Observable<Boolean> construct() {
return Observable.create(new OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> s) {
results.isContextInitialized.set(HystrixRequestContext.isCurrentThreadInitialized());
results.originThread.set(Thread.currentThread());
throw new RuntimeException("bad onError");
}
}).subscribeOn(userScheduler);
}
};
results.command = command;
command.toObservable().doOnEach(new Action1<Notification<? super Boolean>>() {
@Override
public void call(Notification<? super Boolean> n) {
results.isContextInitializedObserveOn.set(HystrixRequestContext.isCurrentThreadInitialized());
results.observeOnThread.set(Thread.currentThread());
}
}).subscribe(results.ts);
results.ts.awaitTerminalEvent();
System.out.println("Run => Initialized: " + results.isContextInitialized.get() + " Thread: " + results.originThread.get());
System.out.println("Observed => Initialized: " + results.isContextInitializedObserveOn.get() + " Thread: " + results.observeOnThread.get());
assertEquals(1, results.ts.getOnErrorEvents().size());
assertTrue(command.getExecutionTimeInMilliseconds() > -1);
assertFalse(command.isSuccessfulExecution());
assertTrue(command.isFailedExecution());
assertCommandExecutionEvents(command, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_MISSING);
assertEquals(0, command.metrics.getCurrentConcurrentExecutionCount());
assertSaneHystrixRequestLog(1);
return results;
}
use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testRejectedViaThreadIsolation.
@Test
public void testRejectedViaThreadIsolation() throws InterruptedException {
final TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
final ArrayBlockingQueue<Boolean> results = new ArrayBlockingQueue<Boolean>(10);
final List<Thread> executionThreads = Collections.synchronizedList(new ArrayList<Thread>(20));
final List<Thread> responseThreads = Collections.synchronizedList(new ArrayList<Thread>(10));
final AtomicBoolean exceptionReceived = new AtomicBoolean();
final CountDownLatch scheduleLatch = new CountDownLatch(2);
final CountDownLatch successLatch = new CountDownLatch(1);
final AtomicInteger count = new AtomicInteger();
final AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand> command1Ref = new AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand>();
final AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand> command2Ref = new AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand>();
final AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand> command3Ref = new AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand>();
Runnable r1 = new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {
@Override
public void run() {
final boolean shouldExecute = count.incrementAndGet() < 3;
try {
executionThreads.add(Thread.currentThread());
TestThreadIsolationWithSemaphoreSetSmallCommand command1 = new TestThreadIsolationWithSemaphoreSetSmallCommand(circuitBreaker, 2, new Action0() {
@Override
public void call() {
// make sure it's deterministic and we put 2 threads into the pool before the 3rd is submitted
if (shouldExecute) {
try {
scheduleLatch.countDown();
successLatch.await();
} catch (InterruptedException e) {
}
}
}
});
command1Ref.set(command1);
results.add(command1.toObservable().map(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean b) {
responseThreads.add(Thread.currentThread());
return b;
}
}).doAfterTerminate(new Action0() {
@Override
public void call() {
if (!shouldExecute) {
// the final thread that shouldn't execute releases the latch once it has run
// so it is deterministic that the other two fill the thread pool until this one rejects
successLatch.countDown();
}
}
}).toBlocking().single());
} catch (Exception e) {
e.printStackTrace();
exceptionReceived.set(true);
}
}
});
Runnable r2 = new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {
@Override
public void run() {
final boolean shouldExecute = count.incrementAndGet() < 3;
try {
executionThreads.add(Thread.currentThread());
TestThreadIsolationWithSemaphoreSetSmallCommand command2 = new TestThreadIsolationWithSemaphoreSetSmallCommand(circuitBreaker, 2, new Action0() {
@Override
public void call() {
// make sure it's deterministic and we put 2 threads into the pool before the 3rd is submitted
if (shouldExecute) {
try {
scheduleLatch.countDown();
successLatch.await();
} catch (InterruptedException e) {
}
}
}
});
command2Ref.set(command2);
results.add(command2.toObservable().map(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean b) {
responseThreads.add(Thread.currentThread());
return b;
}
}).doAfterTerminate(new Action0() {
@Override
public void call() {
if (!shouldExecute) {
// the final thread that shouldn't execute releases the latch once it has run
// so it is deterministic that the other two fill the thread pool until this one rejects
successLatch.countDown();
}
}
}).toBlocking().single());
} catch (Exception e) {
e.printStackTrace();
exceptionReceived.set(true);
}
}
});
Runnable r3 = new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {
@Override
public void run() {
final boolean shouldExecute = count.incrementAndGet() < 3;
try {
executionThreads.add(Thread.currentThread());
TestThreadIsolationWithSemaphoreSetSmallCommand command3 = new TestThreadIsolationWithSemaphoreSetSmallCommand(circuitBreaker, 2, new Action0() {
@Override
public void call() {
// make sure it's deterministic and we put 2 threads into the pool before the 3rd is submitted
if (shouldExecute) {
try {
scheduleLatch.countDown();
successLatch.await();
} catch (InterruptedException e) {
}
}
}
});
command3Ref.set(command3);
results.add(command3.toObservable().map(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean b) {
responseThreads.add(Thread.currentThread());
return b;
}
}).doAfterTerminate(new Action0() {
@Override
public void call() {
if (!shouldExecute) {
// the final thread that shouldn't execute releases the latch once it has run
// so it is deterministic that the other two fill the thread pool until this one rejects
successLatch.countDown();
}
}
}).toBlocking().single());
} catch (Exception e) {
e.printStackTrace();
exceptionReceived.set(true);
}
}
});
// 2 threads, the second should be rejected by the semaphore and return fallback
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
Thread t3 = new Thread(r3);
t1.start();
t2.start();
// wait for the previous 2 thread to be running before starting otherwise it can race
scheduleLatch.await(500, TimeUnit.MILLISECONDS);
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (Exception e) {
e.printStackTrace();
fail("failed waiting on threads");
}
// we should have 2 of the 3 return results
assertEquals(2, results.size());
// the other thread should have thrown an Exception
assertTrue(exceptionReceived.get());
assertCommandExecutionEvents(command1Ref.get(), HystrixEventType.EMIT, HystrixEventType.SUCCESS);
assertCommandExecutionEvents(command2Ref.get(), HystrixEventType.EMIT, HystrixEventType.SUCCESS);
assertCommandExecutionEvents(command3Ref.get(), HystrixEventType.THREAD_POOL_REJECTED, HystrixEventType.FALLBACK_MISSING);
assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
assertSaneHystrixRequestLog(3);
}
use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testBadRequestExceptionObserve.
private void testBadRequestExceptionObserve(ExecutionIsolationStrategy isolationStrategy, boolean asyncException) {
TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
KnownHystrixBadRequestFailureTestCommand command1 = new KnownHystrixBadRequestFailureTestCommand(circuitBreaker, isolationStrategy, asyncException);
try {
command1.observe().toBlocking().single();
fail("we expect to receive a " + HystrixBadRequestException.class.getSimpleName());
} catch (HystrixBadRequestException e) {
// success
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
fail("We expect a " + HystrixBadRequestException.class.getSimpleName() + " but got a " + e.getClass().getSimpleName());
}
assertCommandExecutionEvents(command1, HystrixEventType.BAD_REQUEST);
assertSaneHystrixRequestLog(1);
assertNotNull(command1.getExecutionException());
}
Aggregations