use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testShortCircuitFallbackCounter.
/**
* Test that the circuit-breaker counts a command execution timeout as a 'timeout' and not just failure.
*/
@Test
public void testShortCircuitFallbackCounter() {
TestCircuitBreaker circuitBreaker = new TestCircuitBreaker().setForceShortCircuit(true);
KnownFailureTestCommandWithFallback command1 = new KnownFailureTestCommandWithFallback(circuitBreaker, ExecutionIsolationStrategy.SEMAPHORE, true);
KnownFailureTestCommandWithFallback command2 = new KnownFailureTestCommandWithFallback(circuitBreaker, ExecutionIsolationStrategy.SEMAPHORE, true);
try {
command1.observe().toBlocking().single();
command2.observe().toBlocking().single();
// will be -1 because it never attempted execution
assertEquals(-1, command2.getExecutionTimeInMilliseconds());
assertTrue(command2.isResponseShortCircuited());
assertFalse(command2.isResponseTimedOut());
assertNotNull(command2.getExecutionException());
// semaphore isolated
assertFalse(command2.isExecutedInThread());
} catch (Exception e) {
e.printStackTrace();
fail("We should have received a response from the fallback.");
}
assertCommandExecutionEvents(command1, HystrixEventType.SHORT_CIRCUITED, HystrixEventType.FALLBACK_EMIT, HystrixEventType.FALLBACK_SUCCESS);
assertCommandExecutionEvents(command2, HystrixEventType.SHORT_CIRCUITED, HystrixEventType.FALLBACK_EMIT, HystrixEventType.FALLBACK_SUCCESS);
assertSaneHystrixRequestLog(2);
}
use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testRequestCacheWithSlowExecution.
/**
* Test Request scoped caching of commands so that a 2nd duplicate call doesn't execute but returns the previous Future
*/
@Test
public void testRequestCacheWithSlowExecution() {
TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
SlowCacheableCommand command1 = new SlowCacheableCommand(circuitBreaker, "A", 200);
SlowCacheableCommand command2 = new SlowCacheableCommand(circuitBreaker, "A", 100);
SlowCacheableCommand command3 = new SlowCacheableCommand(circuitBreaker, "A", 100);
SlowCacheableCommand command4 = new SlowCacheableCommand(circuitBreaker, "A", 100);
Future<String> f1 = command1.observe().toBlocking().toFuture();
Future<String> f2 = command2.observe().toBlocking().toFuture();
Future<String> f3 = command3.observe().toBlocking().toFuture();
Future<String> f4 = command4.observe().toBlocking().toFuture();
try {
assertEquals("A", f2.get());
assertEquals("A", f3.get());
assertEquals("A", f4.get());
assertEquals("A", f1.get());
} catch (Exception e) {
throw new RuntimeException(e);
}
assertTrue(command1.executed);
// the second one should not have executed as it should have received the cached value instead
assertFalse(command2.executed);
assertFalse(command3.executed);
assertFalse(command4.executed);
// the execution log for command1 should show an EMIT and a SUCCESS
assertCommandExecutionEvents(command1, HystrixEventType.EMIT, HystrixEventType.SUCCESS);
assertTrue(command1.getExecutionTimeInMilliseconds() > -1);
assertFalse(command1.isResponseFromCache());
// the execution log for command2 should show it came from cache
assertCommandExecutionEvents(command2, HystrixEventType.EMIT, HystrixEventType.SUCCESS, HystrixEventType.RESPONSE_FROM_CACHE);
assertTrue(command2.getExecutionTimeInMilliseconds() == -1);
assertTrue(command2.isResponseFromCache());
assertCommandExecutionEvents(command3, HystrixEventType.EMIT, HystrixEventType.SUCCESS, HystrixEventType.RESPONSE_FROM_CACHE);
assertTrue(command3.isResponseFromCache());
assertTrue(command3.getExecutionTimeInMilliseconds() == -1);
assertCommandExecutionEvents(command4, HystrixEventType.EMIT, HystrixEventType.SUCCESS, HystrixEventType.RESPONSE_FROM_CACHE);
assertTrue(command4.isResponseFromCache());
assertTrue(command4.getExecutionTimeInMilliseconds() == -1);
assertSaneHystrixRequestLog(4);
// semaphore isolated
assertFalse(command1.isExecutedInThread());
assertFalse(command2.isExecutedInThread());
assertFalse(command3.isExecutedInThread());
assertFalse(command4.isExecutedInThread());
}
use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testSemaphorePermitsInUse.
@Test
public void testSemaphorePermitsInUse() {
// this semaphore will be shared across multiple command instances
final TryableSemaphoreActual sharedSemaphore = new TryableSemaphoreActual(HystrixProperty.Factory.asProperty(3));
// creates thread using isolated semaphore
final TryableSemaphoreActual isolatedSemaphore = new TryableSemaphoreActual(HystrixProperty.Factory.asProperty(1));
final TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
// used to wait until all commands are started
final CountDownLatch startLatch = new CountDownLatch((sharedSemaphore.numberOfPermits.get()) * 2 + 1);
// used to signal that all command can finish
final CountDownLatch sharedLatch = new CountDownLatch(1);
final CountDownLatch isolatedLatch = new CountDownLatch(1);
final List<HystrixObservableCommand<Boolean>> commands = new ArrayList<HystrixObservableCommand<Boolean>>();
final List<Observable<Boolean>> results = new ArrayList<Observable<Boolean>>();
HystrixObservableCommand<Boolean> isolated = new LatchedSemaphoreCommand("ObservableCommand-Isolated", circuitBreaker, isolatedSemaphore, startLatch, isolatedLatch);
commands.add(isolated);
for (int s = 0; s < sharedSemaphore.numberOfPermits.get() * 2; s++) {
HystrixObservableCommand<Boolean> shared = new LatchedSemaphoreCommand("ObservableCommand-Shared", circuitBreaker, sharedSemaphore, startLatch, sharedLatch);
commands.add(shared);
Observable<Boolean> result = shared.toObservable();
results.add(result);
}
Observable<Boolean> isolatedResult = isolated.toObservable();
results.add(isolatedResult);
// verifies no permits in use before starting commands
assertEquals("before commands start, shared semaphore should be unused", 0, sharedSemaphore.getNumberOfPermitsUsed());
assertEquals("before commands start, isolated semaphore should be unused", 0, isolatedSemaphore.getNumberOfPermitsUsed());
final CountDownLatch allTerminal = new CountDownLatch(1);
Observable.merge(results).subscribeOn(Schedulers.computation()).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
System.out.println(Thread.currentThread().getName() + " OnCompleted");
allTerminal.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(Thread.currentThread().getName() + " OnError : " + e);
allTerminal.countDown();
}
@Override
public void onNext(Boolean b) {
System.out.println(Thread.currentThread().getName() + " OnNext : " + b);
}
});
try {
assertTrue(startLatch.await(20, TimeUnit.SECONDS));
} catch (Throwable ex) {
fail(ex.getMessage());
}
// verifies that all semaphores are in use
assertEquals("immediately after command start, all shared semaphores should be in-use", sharedSemaphore.numberOfPermits.get().longValue(), sharedSemaphore.getNumberOfPermitsUsed());
assertEquals("immediately after command start, isolated semaphore should be in-use", isolatedSemaphore.numberOfPermits.get().longValue(), isolatedSemaphore.getNumberOfPermitsUsed());
// signals commands to finish
sharedLatch.countDown();
isolatedLatch.countDown();
try {
assertTrue(allTerminal.await(5000, TimeUnit.MILLISECONDS));
} catch (Exception e) {
e.printStackTrace();
fail("failed waiting on commands");
}
// verifies no permits in use after finishing threads
assertEquals("after all threads have finished, no shared semaphores should be in-use", 0, sharedSemaphore.getNumberOfPermitsUsed());
assertEquals("after all threads have finished, isolated semaphore not in-use", 0, isolatedSemaphore.getNumberOfPermitsUsed());
// verifies that some executions failed
int numSemaphoreRejected = 0;
for (HystrixObservableCommand<Boolean> cmd : commands) {
if (cmd.isResponseSemaphoreRejected()) {
numSemaphoreRejected++;
}
}
assertEquals("expected some of shared semaphore commands to get rejected", sharedSemaphore.numberOfPermits.get().longValue(), numSemaphoreRejected);
}
use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testCheckedExceptionViaExecute.
/**
* Test a checked Exception being thrown
*/
@Test
public void testCheckedExceptionViaExecute() {
TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
CommandWithCheckedException command = new CommandWithCheckedException(circuitBreaker);
try {
command.observe().toBlocking().single();
fail("we expect to receive a " + Exception.class.getSimpleName());
} catch (Exception e) {
assertEquals("simulated checked exception message", e.getCause().getMessage());
}
assertEquals("simulated checked exception message", command.getFailedExecutionException().getMessage());
assertTrue(command.getExecutionTimeInMilliseconds() > -1);
assertTrue(command.isFailedExecution());
assertNotNull(command.getExecutionException());
assertCommandExecutionEvents(command, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_MISSING);
assertSaneHystrixRequestLog(1);
}
use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.
the class HystrixCommandTest method testRequestCacheViaExecuteSemaphore1.
/**
* Test Request scoped caching with a mixture of commands
*/
@Test
public void testRequestCacheViaExecuteSemaphore1() {
TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
SuccessfulCacheableCommandViaSemaphore command1 = new SuccessfulCacheableCommandViaSemaphore(circuitBreaker, true, "A");
SuccessfulCacheableCommandViaSemaphore command2 = new SuccessfulCacheableCommandViaSemaphore(circuitBreaker, true, "B");
SuccessfulCacheableCommandViaSemaphore command3 = new SuccessfulCacheableCommandViaSemaphore(circuitBreaker, true, "A");
assertFalse(command1.isCommandRunningInThread());
String f1 = command1.execute();
String f2 = command2.execute();
String f3 = command3.execute();
assertEquals("A", f1);
assertEquals("B", f2);
assertEquals("A", f3);
assertTrue(command1.executed);
// both should execute as they are different
assertTrue(command2.executed);
// but the 3rd should come from cache
assertFalse(command3.executed);
assertCommandExecutionEvents(command1, HystrixEventType.SUCCESS);
assertCommandExecutionEvents(command2, HystrixEventType.SUCCESS);
assertCommandExecutionEvents(command3, HystrixEventType.SUCCESS, HystrixEventType.RESPONSE_FROM_CACHE);
assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
assertSaneHystrixRequestLog(3);
}
Aggregations