Search in sources :

Example 61 with TestCircuitBreaker

use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.

the class HystrixCommandTest method testBadRequestExceptionViaExecuteInSemaphore.

/**
     * Test that a BadRequestException can be thrown and not count towards errors and bypasses fallback.
     */
@Test
public void testBadRequestExceptionViaExecuteInSemaphore() {
    TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
    BadRequestCommand command1 = new BadRequestCommand(circuitBreaker, ExecutionIsolationStrategy.SEMAPHORE);
    try {
        command1.execute();
        fail("we expect to receive a " + HystrixBadRequestException.class.getSimpleName());
    } catch (HystrixBadRequestException e) {
        // success
        e.printStackTrace();
    }
    assertCommandExecutionEvents(command1, HystrixEventType.BAD_REQUEST);
    assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(1);
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) Test(org.junit.Test)

Example 62 with TestCircuitBreaker

use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.

the class HystrixCommandTest method testExceptionConvertedToBadRequestExceptionInExecutionHookBypassesCircuitBreaker.

@Test
public void testExceptionConvertedToBadRequestExceptionInExecutionHookBypassesCircuitBreaker() {
    TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
    ExceptionToBadRequestByExecutionHookCommand command = new ExceptionToBadRequestByExecutionHookCommand(circuitBreaker, ExecutionIsolationStrategy.THREAD);
    try {
        command.execute();
        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(command, HystrixEventType.BAD_REQUEST);
    assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(1);
}
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) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) CancellationException(java.util.concurrent.CancellationException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Example 63 with TestCircuitBreaker

use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.

the class HystrixCommandTest method testSemaphorePermitsInUse.

/**
     * Tests that semaphores are counted separately for commands with unique keys
     */
@Test
public void testSemaphorePermitsInUse() throws Exception {
    final TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
    // this semaphore will be shared across multiple command instances
    final TryableSemaphoreActual sharedSemaphore = new TryableSemaphoreActual(HystrixProperty.Factory.asProperty(3));
    // used to wait until all commands have 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);
    // tracks failures to obtain semaphores
    final AtomicInteger failureCount = new AtomicInteger();
    final Runnable sharedSemaphoreRunnable = new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {

        public void run() {
            try {
                new LatchedSemaphoreCommand("Command-Shared", circuitBreaker, sharedSemaphore, startLatch, sharedLatch).execute();
            } catch (Exception e) {
                startLatch.countDown();
                e.printStackTrace();
                failureCount.incrementAndGet();
            }
        }
    });
    // creates group of threads each using command sharing a single semaphore
    // I create extra threads and commands so that I can verify that some of them fail to obtain a semaphore
    final int sharedThreadCount = sharedSemaphore.numberOfPermits.get() * 2;
    final Thread[] sharedSemaphoreThreads = new Thread[sharedThreadCount];
    for (int i = 0; i < sharedThreadCount; i++) {
        sharedSemaphoreThreads[i] = new Thread(sharedSemaphoreRunnable);
    }
    // creates thread using isolated semaphore
    final TryableSemaphoreActual isolatedSemaphore = new TryableSemaphoreActual(HystrixProperty.Factory.asProperty(1));
    final CountDownLatch isolatedLatch = new CountDownLatch(1);
    final Thread isolatedThread = new Thread(new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {

        public void run() {
            try {
                new LatchedSemaphoreCommand("Command-Isolated", circuitBreaker, isolatedSemaphore, startLatch, isolatedLatch).execute();
            } catch (Exception e) {
                startLatch.countDown();
                e.printStackTrace();
                failureCount.incrementAndGet();
            }
        }
    }));
    // verifies no permits in use before starting threads
    assertEquals("before threads start, shared semaphore should be unused", 0, sharedSemaphore.getNumberOfPermitsUsed());
    assertEquals("before threads start, isolated semaphore should be unused", 0, isolatedSemaphore.getNumberOfPermitsUsed());
    for (int i = 0; i < sharedThreadCount; i++) {
        sharedSemaphoreThreads[i].start();
    }
    isolatedThread.start();
    // waits until all commands have started
    startLatch.await(1000, TimeUnit.MILLISECONDS);
    // 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();
    for (int i = 0; i < sharedThreadCount; i++) {
        sharedSemaphoreThreads[i].join();
    }
    isolatedThread.join();
    // verifies no permits in use after finishing threads
    System.out.println("REQLOG : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
    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
    assertEquals("expected some of shared semaphore commands to get rejected", sharedSemaphore.numberOfPermits.get().longValue(), failureCount.get());
    assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixContextRunnable(com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable) TryableSemaphoreActual(com.netflix.hystrix.AbstractCommand.TryableSemaphoreActual) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HystrixContextRunnable(com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable) CountDownLatch(java.util.concurrent.CountDownLatch) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) CancellationException(java.util.concurrent.CancellationException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Example 64 with TestCircuitBreaker

use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.

the class HystrixCommandTest method testRejectedThreadWithFallbackFailure.

/**
     * Test when a command fails to get queued up in the threadpool where the command implemented getFallback but it fails.
     * <p>
     * We specifically want to protect against developers getting random thread exceptions and instead just correctly receives an HystrixRuntimeException.
     */
@Test
public void testRejectedThreadWithFallbackFailure() throws ExecutionException, InterruptedException {
    TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
    SingleThreadedPoolWithQueue pool = new SingleThreadedPoolWithQueue(1);
    HystrixCommandKey key = HystrixCommandKey.Factory.asKey("Rejection-A");
    //this should pass through the queue and sit in the pool
    TestCommandRejection command1 = new TestCommandRejection(key, circuitBreaker, pool, 500, 600, TestCommandRejection.FALLBACK_FAILURE);
    //this should sit in the queue
    TestCommandRejection command2 = new TestCommandRejection(key, circuitBreaker, pool, 500, 600, TestCommandRejection.FALLBACK_SUCCESS);
    //this should observe full queue and get rejected
    TestCommandRejection command3 = new TestCommandRejection(key, circuitBreaker, pool, 500, 600, TestCommandRejection.FALLBACK_FAILURE);
    Future<Boolean> f1 = null;
    Future<Boolean> f2 = null;
    try {
        f1 = command1.queue();
        f2 = command2.queue();
        //should get thread-pool rejected
        assertEquals(false, command3.queue().get());
        fail("we shouldn't get here");
    } catch (Exception e) {
        e.printStackTrace();
        if (e instanceof HystrixRuntimeException && e.getCause() instanceof RejectedExecutionException) {
            HystrixRuntimeException de = (HystrixRuntimeException) e;
            assertNotNull(de.getFallbackException());
            assertFalse(de.getFallbackException() instanceof UnsupportedOperationException);
            assertNotNull(de.getImplementingClass());
            assertNotNull(de.getCause());
            assertTrue(de.getCause() instanceof RejectedExecutionException);
        } else {
            fail("the exception should be HystrixRuntimeException with cause as RejectedExecutionException");
        }
    }
    //still in-flight, no events yet
    assertCommandExecutionEvents(command1);
    //still in-flight, no events yet
    assertCommandExecutionEvents(command2);
    assertCommandExecutionEvents(command3, HystrixEventType.THREAD_POOL_REJECTED, HystrixEventType.FALLBACK_FAILURE);
    int numInFlight = circuitBreaker.metrics.getCurrentConcurrentExecutionCount();
    //pool-filler still going
    assertTrue("Expected at most 1 in flight but got : " + numInFlight, numInFlight <= 1);
    //This is a case where we knowingly walk away from executing Hystrix threads. They should have an in-flight status ("Executed").  You should avoid this in a production environment
    HystrixRequestLog requestLog = HystrixRequestLog.getCurrentRequest();
    assertEquals(3, requestLog.getAllExecutedCommands().size());
    assertTrue(requestLog.getExecutedCommandsAsString().contains("Executed"));
    //block on the outstanding work, so we don't inadvertently affect any other tests
    long startTime = System.currentTimeMillis();
    f1.get();
    f2.get();
    assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
    System.out.println("Time blocked : " + (System.currentTimeMillis() - startTime));
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) CancellationException(java.util.concurrent.CancellationException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Test(org.junit.Test)

Example 65 with TestCircuitBreaker

use of com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker in project Hystrix by Netflix.

the class HystrixCommandTest method testCheckedExceptionViaObserve.

/**
     * Test a java.lang.Error being thrown
     *
     * @throws InterruptedException
     */
@Test
public void testCheckedExceptionViaObserve() throws InterruptedException {
    TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
    CommandWithCheckedException command = new CommandWithCheckedException(circuitBreaker);
    final AtomicReference<Throwable> t = new AtomicReference<Throwable>();
    final CountDownLatch latch = new CountDownLatch(1);
    try {
        command.observe().subscribe(new Observer<Boolean>() {

            @Override
            public void onCompleted() {
                latch.countDown();
            }

            @Override
            public void onError(Throwable e) {
                t.set(e);
                latch.countDown();
            }

            @Override
            public void onNext(Boolean args) {
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
        fail("we should not get anything thrown, it should be emitted via the Observer#onError method");
    }
    latch.await(1, TimeUnit.SECONDS);
    assertNotNull(t.get());
    t.get().printStackTrace();
    assertTrue(t.get() instanceof HystrixRuntimeException);
    assertEquals("simulated checked exception message", t.get().getCause().getMessage());
    assertEquals("simulated checked exception message", command.getFailedExecutionException().getMessage());
    assertTrue(command.getExecutionTimeInMilliseconds() > -1);
    assertTrue(command.isFailedExecution());
    assertCommandExecutionEvents(command, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_MISSING);
    assertNotNull(command.getExecutionException());
    assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(1);
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) AtomicReference(java.util.concurrent.atomic.AtomicReference) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) CancellationException(java.util.concurrent.CancellationException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

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