Search in sources :

Example 71 with TestCircuitBreaker

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);
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Example 72 with TestCircuitBreaker

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());
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) Test(org.junit.Test)

Example 73 with TestCircuitBreaker

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;
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) Action1(rx.functions.Action1) TestSubscriber(rx.observers.TestSubscriber) Subscriber(rx.Subscriber) OnSubscribe(rx.Observable.OnSubscribe) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Notification(rx.Notification)

Example 74 with TestCircuitBreaker

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);
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) Action0(rx.functions.Action0) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) HystrixContextRunnable(com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HystrixContextRunnable(com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Func1(rx.functions.Func1) Test(org.junit.Test)

Example 75 with TestCircuitBreaker

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());
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

TestCircuitBreaker (com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker)82 Test (org.junit.Test)70 HystrixRuntimeException (com.netflix.hystrix.exception.HystrixRuntimeException)46 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)43 ExecutionException (java.util.concurrent.ExecutionException)40 HystrixBadRequestException (com.netflix.hystrix.exception.HystrixBadRequestException)37 IOException (java.io.IOException)33 TimeoutException (java.util.concurrent.TimeoutException)33 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)18 CancellationException (java.util.concurrent.CancellationException)17 HystrixContextRunnable (com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable)10 CountDownLatch (java.util.concurrent.CountDownLatch)10 Notification (rx.Notification)7 OnSubscribe (rx.Observable.OnSubscribe)7 Subscriber (rx.Subscriber)7 Action1 (rx.functions.Action1)7 TestSubscriber (rx.observers.TestSubscriber)7 TryableSemaphoreActual (com.netflix.hystrix.AbstractCommand.TryableSemaphoreActual)6 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)5