From ff019e7804cec61fd5e7b95bd749f42e61d3b1d8 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 24 Apr 2016 15:53:02 -0300 Subject: [PATCH] more tests using HystrixRequestContext rule refs https://github.com/Netflix/Hystrix/pull/1184 and https://github.com/Netflix/Hystrix/pull/1147 --- hystrix-core/build.gradle | 3 +- .../netflix/hystrix/HystrixCollapserTest.java | 24 +- .../netflix/hystrix/HystrixCommandTest.java | 25 +- .../HystrixObservableCollapserTest.java | 27 +-- .../hystrix/HystrixObservableCommandTest.java | 143 ++++++------ .../hystrix/HystrixRequestLogTest.java | 219 ++++++++---------- .../hystrix/HystrixSubclassCommandTest.java | 18 +- 7 files changed, 190 insertions(+), 269 deletions(-) diff --git a/hystrix-core/build.gradle b/hystrix-core/build.gradle index 640e0930a..5feef79a2 100644 --- a/hystrix-core/build.gradle +++ b/hystrix-core/build.gradle @@ -7,6 +7,7 @@ dependencies { compile 'org.slf4j:slf4j-api:1.7.0' compile 'org.hdrhistogram:HdrHistogram:2.1.7' testCompile 'junit:junit-dep:4.10' + testCompile project(':hystrix-junit') } @@ -44,4 +45,4 @@ jmh { warmup = '1s' warmupBatchSize = 1 warmupIterations = 5 -} \ No newline at end of file +} diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCollapserTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCollapserTest.java index 97f47724e..abc4f66ef 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCollapserTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCollapserTest.java @@ -15,6 +15,7 @@ */ package com.netflix.hystrix; +import com.hystrix.junit.HystrixRequestContextRule; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.util.ArrayList; @@ -28,9 +29,8 @@ import java.util.concurrent.atomic.AtomicInteger; import com.netflix.hystrix.strategy.properties.HystrixPropertiesCollapserDefault; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import com.netflix.hystrix.HystrixCollapser.CollapsedRequest; @@ -48,21 +48,13 @@ import static org.junit.Assert.*; public class HystrixCollapserTest { - private HystrixRequestContext context = null; + @Rule + public HystrixRequestContextRule context = new HystrixRequestContextRule(); @Before public void init() { - // since we're going to modify properties of the same class between tests, wipe the cache each time - HystrixCollapser.reset(); HystrixCollapserMetrics.reset(); HystrixCommandMetrics.reset(); - /* we must call this to simulate a new request lifecycle running and clearing caches */ - context = HystrixRequestContext.initializeContext(); - } - - @After - public void cleanup() { - context.shutdown(); } @Test @@ -827,7 +819,7 @@ public void testRequestWithCommandShortCircuited() throws Exception { /** * Test a Void response type - null being set as response. - * + * * @throws Exception */ @Test @@ -851,7 +843,7 @@ public void testVoidResponseTypeFireAndForgetCollapsing1() throws Exception { /** * Test a Void response type - response never being set in mapResponseToRequest - * + * * @throws Exception */ @Test @@ -879,7 +871,7 @@ public void testVoidResponseTypeFireAndForgetCollapsing2() throws Exception { /** * Test a Void response type with execute - response being set in mapResponseToRequest to null - * + * * @throws Exception */ @Test @@ -1198,7 +1190,7 @@ public void clear() { * You must call incrementTime multiple times each increment being larger than 'period' on subsequent calls to cause multiple executions. *

* This is because executing multiple times in a tight-loop would not achieve the correct behavior, such as batching, since it will all execute "now" not after intervals of time. - * + * * @param timeInMilliseconds amount of time to increment */ public synchronized void incrementTime(int timeInMilliseconds) { diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandTest.java index 262c94e63..ab869b093 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandTest.java @@ -15,6 +15,7 @@ */ package com.netflix.hystrix; +import com.hystrix.junit.HystrixRequestContextRule; import com.netflix.config.ConfigurationManager; import com.netflix.hystrix.AbstractCommand.TryableSemaphore; import com.netflix.hystrix.AbstractCommand.TryableSemaphoreActual; @@ -29,7 +30,7 @@ import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; import com.netflix.hystrix.strategy.properties.HystrixProperty; import org.junit.After; -import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import rx.Observable; import rx.Observer; @@ -57,21 +58,11 @@ import static org.junit.Assert.*; public class HystrixCommandTest extends CommonHystrixCommandTests> { - - @Before - public void prepareForTest() { - /* we must call this to simulate a new request lifecycle running and clearing caches */ - HystrixRequestContext.initializeContext(); - } + @Rule + public HystrixRequestContextRule ctx = new HystrixRequestContextRule(); @After public void cleanup() { - // instead of storing the reference from initialize we'll just get the current state and shutdown - if (HystrixRequestContext.getContextForCurrentThread() != null) { - // it could have been set NULL by the test - HystrixRequestContext.getContextForCurrentThread().shutdown(); - } - // force properties to be clean as well ConfigurationManager.getConfigInstance().clear(); @@ -2374,7 +2365,7 @@ public void testBadRequestExceptionViaQueueInThread() { } catch (ExecutionException e) { e.printStackTrace(); if (e.getCause() instanceof HystrixBadRequestException) { - // success + // success } else { fail("We expect a " + HystrixBadRequestException.class.getSimpleName() + " but got a " + e.getClass().getSimpleName()); } @@ -2413,7 +2404,7 @@ public void testBadRequestExceptionViaQueueInThreadOnResponseFromCache() { } catch (ExecutionException e) { e.printStackTrace(); if (e.getCause() instanceof HystrixBadRequestException) { - // success + // success } else { fail("We expect a " + HystrixBadRequestException.class.getSimpleName() + " but got a " + e.getClass().getSimpleName()); } @@ -2477,7 +2468,7 @@ public void testCheckedExceptionViaExecute() { /** * Test a java.lang.Error being thrown - * + * * @throws InterruptedException */ @Test @@ -3809,7 +3800,7 @@ private static class LatchedSemaphoreCommand extends TestHystrixCommand private final CountDownLatch startLatch, waitLatch; /** - * + * * @param circuitBreaker circuit breaker (passed in so it may be shared) * @param semaphore semaphore (passed in so it may be shared) * @param startLatch diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixObservableCollapserTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixObservableCollapserTest.java index 3b47d2912..5a3a6d2de 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixObservableCollapserTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixObservableCollapserTest.java @@ -1,12 +1,12 @@ /** * Copyright 2014 Netflix, Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,6 +15,7 @@ */ package com.netflix.hystrix; +import com.hystrix.junit.HystrixRequestContextRule; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -35,8 +36,8 @@ import com.netflix.hystrix.collapser.RealCollapserTimer; import com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable; import com.netflix.hystrix.strategy.properties.HystrixPropertiesCollapserDefault; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import rx.Observable; @@ -122,24 +123,14 @@ public String call(String s) { } }; + @Rule + public HystrixRequestContextRule ctx = new HystrixRequestContextRule(); private static ExecutorService threadPool = new ThreadPoolExecutor(100, 100, 10, TimeUnit.MINUTES, new SynchronousQueue()); @Before public void init() { // since we're going to modify properties of the same class between tests, wipe the cache each time HystrixCollapser.reset(); - Hystrix.reset(); - /* we must call this to simulate a new request lifecycle running and clearing caches */ - HystrixRequestContext.initializeContext(); - } - - @After - public void cleanup() { - // instead of storing the reference from initialize we'll just get the current state and shutdown - if (HystrixRequestContext.getContextForCurrentThread() != null) { - // it may be null if a test shuts the context down manually - HystrixRequestContext.getContextForCurrentThread().shutdown(); - } } @Test @@ -165,7 +156,7 @@ public void stressTestRequestCollapser() throws Exception { for(int i = 0; i < 10; i++) { init(); testTwoRequests(); - cleanup(); + ctx.reset(); } } @@ -805,7 +796,7 @@ public void call(Subscriber s) { } s.onNext(request.getArgument()); } - + s.onCompleted(); } diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixObservableCommandTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixObservableCommandTest.java index 9ed4fa9a6..c04e0c679 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixObservableCommandTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixObservableCommandTest.java @@ -15,6 +15,7 @@ */ package com.netflix.hystrix; +import com.hystrix.junit.HystrixRequestContextRule; import com.netflix.config.ConfigurationManager; import com.netflix.hystrix.AbstractCommand.TryableSemaphoreActual; import com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker; @@ -28,6 +29,7 @@ import com.netflix.hystrix.strategy.properties.HystrixProperty; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import rx.Notification; import rx.Observable; @@ -62,20 +64,11 @@ public class HystrixObservableCommandTest extends CommonHystrixCommandTests> { - @Before - public void prepareForTest() { - /* we must call this to simulate a new request lifecycle running and clearing caches */ - HystrixRequestContext.initializeContext(); - } + @Rule + public HystrixRequestContextRule ctx = new HystrixRequestContextRule(); @After public void cleanup() { - // instead of storing the reference from initialize we'll just get the current state and shutdown - if (HystrixRequestContext.getContextForCurrentThread() != null) { - // it could have been set NULL by the test - HystrixRequestContext.getContextForCurrentThread().shutdown(); - } - // force properties to be clean as well ConfigurationManager.getConfigInstance().clear(); @@ -1834,7 +1827,7 @@ private void testBadRequestExceptionOnResponseFromCache(ExecutionIsolationStrate } catch (ExecutionException e) { e.printStackTrace(); if (e.getCause() instanceof HystrixBadRequestException) { - // success + // success } else { fail("We expect a " + HystrixBadRequestException.class.getSimpleName() + " but got a " + e.getClass().getSimpleName()); } @@ -1876,7 +1869,7 @@ public void testCheckedExceptionViaExecute() { /** * Test a java.lang.Error being thrown - * + * * @throws InterruptedException */ @Test @@ -1929,7 +1922,7 @@ public void onNext(Boolean args) { /** * Test a java.lang.Error being thrown - * + * * @throws InterruptedException */ @Test @@ -3478,9 +3471,9 @@ public void testSuccessfulRequestContextWithSemaphoreIsolatedSynchronousObservab /** * Async Observable and semaphore isolation. User provided thread [RxNewThread] does everything. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3499,7 +3492,7 @@ public void testSuccessfulRequestContextWithSemaphoreIsolatedAsynchronousObserva /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -3535,9 +3528,9 @@ public void testSuccessfulRequestContextWithThreadIsolatedSynchronousObservable( /** * Async Observable and thread isolation. User provided thread [RxNetThread] executes Observable and then [RxComputation] observes the onNext calls. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3556,7 +3549,7 @@ public void testSuccessfulRequestContextWithThreadIsolatedAsynchronousObservable /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -3594,9 +3587,9 @@ public void testGracefulFailureRequestContextWithSemaphoreIsolatedSynchronousObs /** * Async Observable and semaphore isolation. User provided thread [RxNewThread] does everything. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3615,7 +3608,7 @@ public void testGracefulFailureRequestContextWithSemaphoreIsolatedAsynchronousOb /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -3651,9 +3644,9 @@ public void testGracefulFailureRequestContextWithThreadIsolatedSynchronousObserv /** * Async Observable and thread isolation. User provided thread [RxNetThread] executes Observable and then [RxComputation] observes the onNext calls. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3672,7 +3665,7 @@ public void testGracefulFailureRequestContextWithThreadIsolatedAsynchronousObser /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -3710,9 +3703,9 @@ public void testBadFailureRequestContextWithSemaphoreIsolatedSynchronousObservab /** * Async Observable and semaphore isolation. User provided thread [RxNewThread] does everything. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3731,7 +3724,7 @@ public void testBadFailureRequestContextWithSemaphoreIsolatedAsynchronousObserva /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -3767,9 +3760,9 @@ public void testBadFailureRequestContextWithThreadIsolatedSynchronousObservable( /** * Async Observable and thread isolation. User provided thread [RxNetThread] executes Observable and then [RxComputation] observes the onNext calls. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3788,7 +3781,7 @@ public void testBadFailureRequestContextWithThreadIsolatedAsynchronousObservable /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -3826,9 +3819,9 @@ public void testFailureWithFallbackRequestContextWithSemaphoreIsolatedSynchronou /** * Async Observable and semaphore isolation. User provided thread [RxNewThread] does everything. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3847,7 +3840,7 @@ public void testFailureWithFallbackRequestContextWithSemaphoreIsolatedAsynchrono /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -3883,9 +3876,9 @@ public void testFailureWithFallbackRequestContextWithThreadIsolatedSynchronousOb /** * Async Observable and thread isolation. User provided thread [RxNetThread] executes Observable and then [RxComputation] observes the onNext calls. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3904,7 +3897,7 @@ public void testFailureWithFallbackRequestContextWithThreadIsolatedAsynchronousO /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -3942,9 +3935,9 @@ public void testRejectionWithFallbackRequestContextWithSemaphoreIsolatedSynchron /** * Async Observable and semaphore isolation. User provided thread [RxNewThread] does everything. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -3963,7 +3956,7 @@ public void testRejectionWithFallbackRequestContextWithSemaphoreIsolatedAsynchro /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -4000,9 +3993,9 @@ public void testRejectionWithFallbackRequestContextWithThreadIsolatedSynchronous /** * Async Observable and thread isolation. User provided thread [RxNetThread] executes Observable and then [RxComputation] observes the onNext calls. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -4021,7 +4014,7 @@ public void testRejectionWithFallbackRequestContextWithThreadIsolatedAsynchronou /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -4059,9 +4052,9 @@ public void testShortCircuitedWithFallbackRequestContextWithSemaphoreIsolatedSyn /** * Async Observable and semaphore isolation. User provided thread [RxNewThread] does everything. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -4080,7 +4073,7 @@ public void testShortCircuitedWithFallbackRequestContextWithSemaphoreIsolatedAsy /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -4116,9 +4109,9 @@ public void testShortCircuitedWithFallbackRequestContextWithThreadIsolatedSynchr /** * Async Observable and thread isolation. User provided thread [RxNetThread] executes Observable and then [RxComputation] observes the onNext calls. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -4137,7 +4130,7 @@ public void testShortCircuitedWithFallbackRequestContextWithThreadIsolatedAsynch /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -4177,9 +4170,9 @@ public void testTimeoutRequestContextWithSemaphoreIsolatedSynchronousObservable( /** * Async Observable and semaphore isolation. User provided thread [RxNewThread] does everything. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -4200,7 +4193,7 @@ public void testTimeoutRequestContextWithSemaphoreIsolatedAsynchronousObservable /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -4240,9 +4233,9 @@ public void testTimeoutRequestContextWithThreadIsolatedSynchronousObservable() { /** * Async Observable and thread isolation. User provided thread [RxNetThread] executes Observable and then [RxComputation] observes the onNext calls. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -4263,7 +4256,7 @@ public void testTimeoutRequestContextWithThreadIsolatedAsynchronousObservable() /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -4285,14 +4278,14 @@ public void testTimeoutRequestContextWithThreadIsolatedAsynchronousObservableAnd /* *************************************** testTimeoutWithFallbackRequestContext *********************************** */ /** - * Synchronous Observable and semaphore isolation. + * Synchronous Observable and semaphore isolation. */ @Test public void testTimeoutWithFallbackRequestContextWithSemaphoreIsolatedSynchronousObservable() { RequestContextTestResults results = testRequestContextOnTimeoutWithFallback(ExecutionIsolationStrategy.SEMAPHORE, Schedulers.immediate()); assertTrue(results.isContextInitialized.get()); - assertTrue(results.originThread.get().getName().startsWith("HystrixTimer")); // timeout uses HystrixTimer thread + assertTrue(results.originThread.get().getName().startsWith("HystrixTimer")); // timeout uses HystrixTimer thread //(this use case is a little odd as it should generally not be the case that we are "timing out" a synchronous observable on semaphore isolation) assertTrue(results.isContextInitializedObserveOn.get()); @@ -4306,9 +4299,9 @@ public void testTimeoutWithFallbackRequestContextWithSemaphoreIsolatedSynchronou /** * Async Observable and semaphore isolation. User provided thread [RxNewThread] does everything. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -4329,7 +4322,7 @@ public void testTimeoutWithFallbackRequestContextWithSemaphoreIsolatedAsynchrono /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -4369,9 +4362,9 @@ public void testTimeoutWithFallbackRequestContextWithThreadIsolatedSynchronousOb /** * Async Observable and thread isolation. User provided thread [RxNetThread] executes Observable and then [RxComputation] observes the onNext calls. - * + * * NOTE: RequestContext will NOT exist on that thread. - * + * * An async Observable running on its own thread will not have access to the request context unless the user manages the context. */ @Test @@ -4392,7 +4385,7 @@ public void testTimeoutWithFallbackRequestContextWithThreadIsolatedAsynchronousO /** * Async Observable and semaphore isolation WITH functioning RequestContext - * + * * Use HystrixContextScheduler to make the user provided scheduler capture context. */ @Test @@ -4470,7 +4463,7 @@ public void testExecutionPartialSuccess() { fail("We received an exception."); } } - + /** * Test behavior when some onNext are received and then a failure. */ @@ -4483,10 +4476,10 @@ public void testExecutionPartialSuccessWithFallback() { ts.awaitTerminalEvent(); ts.assertReceivedOnNext(Arrays.asList(false, true, false, true, false, true, false)); ts.assertNoErrors(); - + assertFalse(command.isSuccessfulExecution()); assertTrue(command.isFailedExecution()); - + assertNotNull(command.getFailedExecutionException()); assertTrue(command.getExecutionTimeInMilliseconds() > -1); assertCommandExecutionEvents(command, HystrixEventType.EMIT, HystrixEventType.EMIT, HystrixEventType.EMIT, HystrixEventType.FAILURE, @@ -4749,7 +4742,7 @@ protected Observable construct() { } } - + private static class TestPartialSuccessWithFallback extends TestHystrixObservableCommand { TestPartialSuccessWithFallback() { @@ -4770,14 +4763,14 @@ protected Observable construct() { .concatWith(Observable. error(new RuntimeException("forced error"))) .subscribeOn(Schedulers.computation()); } - + @Override protected Observable resumeWithFallback() { return Observable.just(true, false, true, false); } } - + /** * Test how a fallback could be done on a streaming response where it is partially successful * by retaining state of what has been seen. @@ -4789,7 +4782,7 @@ private static class TestPartialSuccessWithIntelligentFallback extends TestHystr } volatile int lastSeen = 0; - + @Override protected Observable construct() { return Observable.just(1, 2, 3) @@ -4800,11 +4793,11 @@ protected Observable construct() { public void call(Integer t1) { lastSeen = t1; } - + }) .subscribeOn(Schedulers.computation()); } - + @Override protected Observable resumeWithFallback() { if (lastSeen < 4) { @@ -5247,7 +5240,7 @@ protected Observable resumeWithFallback() { /** * The construct() will take time once subscribed to. No fallback implementation. - * + * * Used for making sure Thread and Semaphore isolation are separated from each other. */ private static class TestThreadIsolationWithSemaphoreSetSmallCommand extends TestHystrixObservableCommand { @@ -5289,7 +5282,7 @@ private static class LatchedSemaphoreCommand extends TestHystrixObservableComman private final CountDownLatch startLatch, waitLatch; /** - * + * * @param circuitBreaker circuit breaker (passed in so it may be shared) * @param semaphore semaphore (passed in so it may be shared) * @param startLatch diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixRequestLogTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixRequestLogTest.java index 9ff8c51b2..b8bfff5a8 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixRequestLogTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixRequestLogTest.java @@ -15,187 +15,150 @@ */ package com.netflix.hystrix; +import com.hystrix.junit.HystrixRequestContextRule; import static org.junit.Assert.assertEquals; +import org.junit.Rule; import org.junit.Test; -import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; import rx.Observable; -import java.util.ArrayList; -import java.util.List; - public class HystrixRequestLogTest { private static final String DIGITS_REGEX = "\\[\\d+"; + @Rule + public HystrixRequestContextRule ctx = new HystrixRequestContextRule(); + @Test public void testSuccess() { - HystrixRequestContext context = HystrixRequestContext.initializeContext(); - try { - new TestCommand("A", false, true).execute(); - String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); - // strip the actual count so we can compare reliably - log = log.replaceAll(DIGITS_REGEX, "["); - assertEquals("TestCommand[SUCCESS][ms]", log); - } finally { - context.shutdown(); - } + new TestCommand("A", false, true).execute(); + String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); + // strip the actual count so we can compare reliably + log = log.replaceAll(DIGITS_REGEX, "["); + assertEquals("TestCommand[SUCCESS][ms]", log); } @Test public void testSuccessFromCache() { - HystrixRequestContext context = HystrixRequestContext.initializeContext(); - try { - // 1 success - new TestCommand("A", false, true).execute(); - // 4 success from cache - new TestCommand("A", false, true).execute(); - new TestCommand("A", false, true).execute(); - new TestCommand("A", false, true).execute(); - new TestCommand("A", false, true).execute(); - String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); - // strip the actual count so we can compare reliably - log = log.replaceAll(DIGITS_REGEX, "["); - assertEquals("TestCommand[SUCCESS][ms], TestCommand[SUCCESS, RESPONSE_FROM_CACHE][ms]x4", log); - } finally { - context.shutdown(); - } + // 1 success + new TestCommand("A", false, true).execute(); + // 4 success from cache + new TestCommand("A", false, true).execute(); + new TestCommand("A", false, true).execute(); + new TestCommand("A", false, true).execute(); + new TestCommand("A", false, true).execute(); + String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); + // strip the actual count so we can compare reliably + log = log.replaceAll(DIGITS_REGEX, "["); + assertEquals("TestCommand[SUCCESS][ms], TestCommand[SUCCESS, RESPONSE_FROM_CACHE][ms]x4", log); } @Test public void testFailWithFallbackSuccess() { - HystrixRequestContext context = HystrixRequestContext.initializeContext(); - try { - // 1 failure - new TestCommand("A", true, false).execute(); - // 4 failures from cache - new TestCommand("A", true, false).execute(); - new TestCommand("A", true, false).execute(); - new TestCommand("A", true, false).execute(); - new TestCommand("A", true, false).execute(); - String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); - // strip the actual count so we can compare reliably - log = log.replaceAll(DIGITS_REGEX, "["); - assertEquals("TestCommand[FAILURE, FALLBACK_SUCCESS][ms], TestCommand[FAILURE, FALLBACK_SUCCESS, RESPONSE_FROM_CACHE][ms]x4", log); - } finally { - context.shutdown(); - } + // 1 failure + new TestCommand("A", true, false).execute(); + // 4 failures from cache + new TestCommand("A", true, false).execute(); + new TestCommand("A", true, false).execute(); + new TestCommand("A", true, false).execute(); + new TestCommand("A", true, false).execute(); + String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); + // strip the actual count so we can compare reliably + log = log.replaceAll(DIGITS_REGEX, "["); + assertEquals("TestCommand[FAILURE, FALLBACK_SUCCESS][ms], TestCommand[FAILURE, FALLBACK_SUCCESS, RESPONSE_FROM_CACHE][ms]x4", log); } @Test public void testFailWithFallbackFailure() { - HystrixRequestContext context = HystrixRequestContext.initializeContext(); + // 1 failure try { - // 1 failure - try { - new TestCommand("A", true, true).execute(); - } catch (Exception e) { - } - // 1 failure from cache - try { - new TestCommand("A", true, true).execute(); - } catch (Exception e) { - } - String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); - // strip the actual count so we can compare reliably - log = log.replaceAll(DIGITS_REGEX, "["); - assertEquals("TestCommand[FAILURE, FALLBACK_FAILURE][ms], TestCommand[FAILURE, FALLBACK_FAILURE, RESPONSE_FROM_CACHE][ms]", log); - } finally { - context.shutdown(); + new TestCommand("A", true, true).execute(); + } catch (Exception e) { } + // 1 failure from cache + try { + new TestCommand("A", true, true).execute(); + } catch (Exception e) { + } + String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); + // strip the actual count so we can compare reliably + log = log.replaceAll(DIGITS_REGEX, "["); + assertEquals("TestCommand[FAILURE, FALLBACK_FAILURE][ms], TestCommand[FAILURE, FALLBACK_FAILURE, RESPONSE_FROM_CACHE][ms]", log); } @Test public void testTimeout() { - HystrixRequestContext context = HystrixRequestContext.initializeContext(); - try { - Observable result = null; + Observable result = null; - // 1 timeout - try { - for (int i = 0; i < 1; i++) { - result = new TestCommand("A", false, false, true).observe(); - } - } catch (Exception e) { - } - try { - result.toBlocking().single(); - } catch (Throwable ex) { - //ex.printStackTrace(); + // 1 timeout + try { + for (int i = 0; i < 1; i++) { + result = new TestCommand("A", false, false, true).observe(); } - System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " -> done with awaiting all observables"); - String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); - // strip the actual count so we can compare reliably - log = log.replaceAll(DIGITS_REGEX, "["); - assertEquals("TestCommand[TIMEOUT, FALLBACK_MISSING][ms]", log); - } finally { - context.shutdown(); + } catch (Exception e) { + } + try { + result.toBlocking().single(); + } catch (Throwable ex) { + //ex.printStackTrace(); } + System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " -> done with awaiting all observables"); + String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); + // strip the actual count so we can compare reliably + log = log.replaceAll(DIGITS_REGEX, "["); + assertEquals("TestCommand[TIMEOUT, FALLBACK_MISSING][ms]", log); } @Test public void testManyTimeouts() { for (int i = 0; i < 10; i++) { testTimeout(); - Hystrix.reset(); + ctx.reset(); } } @Test public void testMultipleCommands() { + // 1 success + new TestCommand("GetData", "A", false, false).execute(); - HystrixRequestContext context = HystrixRequestContext.initializeContext(); - try { - - // 1 success - new TestCommand("GetData", "A", false, false).execute(); - - // 1 success - new TestCommand("PutData", "B", false, false).execute(); + // 1 success + new TestCommand("PutData", "B", false, false).execute(); - // 1 success - new TestCommand("GetValues", "C", false, false).execute(); + // 1 success + new TestCommand("GetValues", "C", false, false).execute(); - // 1 success from cache - new TestCommand("GetValues", "C", false, false).execute(); + // 1 success from cache + new TestCommand("GetValues", "C", false, false).execute(); - // 1 failure - try { - new TestCommand("A", true, true).execute(); - } catch (Exception e) { - } - // 1 failure from cache - try { - new TestCommand("A", true, true).execute(); - } catch (Exception e) { - } - String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); - // strip the actual count so we can compare reliably - log = log.replaceAll(DIGITS_REGEX, "["); - assertEquals("GetData[SUCCESS][ms], PutData[SUCCESS][ms], GetValues[SUCCESS][ms], GetValues[SUCCESS, RESPONSE_FROM_CACHE][ms], TestCommand[FAILURE, FALLBACK_FAILURE][ms], TestCommand[FAILURE, FALLBACK_FAILURE, RESPONSE_FROM_CACHE][ms]", log); - } finally { - context.shutdown(); + // 1 failure + try { + new TestCommand("A", true, true).execute(); + } catch (Exception e) { } - + // 1 failure from cache + try { + new TestCommand("A", true, true).execute(); + } catch (Exception e) { + } + String log = HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString(); + // strip the actual count so we can compare reliably + log = log.replaceAll(DIGITS_REGEX, "["); + assertEquals("GetData[SUCCESS][ms], PutData[SUCCESS][ms], GetValues[SUCCESS][ms], GetValues[SUCCESS, RESPONSE_FROM_CACHE][ms], TestCommand[FAILURE, FALLBACK_FAILURE][ms], TestCommand[FAILURE, FALLBACK_FAILURE, RESPONSE_FROM_CACHE][ms]", log); } @Test public void testMaxLimit() { - HystrixRequestContext context = HystrixRequestContext.initializeContext(); - try { - for (int i = 0; i < HystrixRequestLog.MAX_STORAGE; i++) { - new TestCommand("A", false, true).execute(); - } - // then execute again some more - for (int i = 0; i < 10; i++) { - new TestCommand("A", false, true).execute(); - } - - assertEquals(HystrixRequestLog.MAX_STORAGE, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size()); - } finally { - context.shutdown(); + for (int i = 0; i < HystrixRequestLog.MAX_STORAGE; i++) { + new TestCommand("A", false, true).execute(); } + // then execute again some more + for (int i = 0; i < 10; i++) { + new TestCommand("A", false, true).execute(); + } + + assertEquals(HystrixRequestLog.MAX_STORAGE, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size()); } private static class TestCommand extends HystrixCommand { @@ -276,4 +239,4 @@ protected String getCacheKey() { } } -} \ No newline at end of file +} diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixSubclassCommandTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixSubclassCommandTest.java index d2b5d097d..d0ab97eb1 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixSubclassCommandTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixSubclassCommandTest.java @@ -16,9 +16,8 @@ package com.netflix.hystrix; -import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; -import org.junit.After; -import org.junit.Before; +import com.hystrix.junit.HystrixRequestContextRule; +import org.junit.Rule; import org.junit.Test; import java.util.ArrayList; @@ -29,17 +28,8 @@ public class HystrixSubclassCommandTest { private final static HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("GROUP"); - private HystrixRequestContext requestContext; - - @Before - public void setUp() { - requestContext = HystrixRequestContext.initializeContext(); - } - - @After - public void tearDown() { - requestContext.shutdown(); - } + @Rule + public HystrixRequestContextRule ctx = new HystrixRequestContextRule(); @Test public void testFallback() {