Use Guice injector for BlockedThreadsCheck in tests
The creation of the BlockedThreadsCheck was never tested
and could have led to severe issues left untested and unnoticed
like the @Singleton annotation on the BlockedThreadsCheck
making the whole check value stateful.
Change-Id: Ibd0ebf86c4524e3f8fb232bb4c97d799c0d0ae80
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/BlockedThreadsCheckTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/BlockedThreadsCheckTest.java
index d50d12a..641a060 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/BlockedThreadsCheckTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/BlockedThreadsCheckTest.java
@@ -20,13 +20,11 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
-import com.google.inject.util.Providers;
import com.googlesource.gerrit.plugins.healthcheck.check.BlockedThreadsCheck;
-import com.googlesource.gerrit.plugins.healthcheck.check.BlockedThreadsConfigurator;
+import com.googlesource.gerrit.plugins.healthcheck.check.BlockedThreadsCheck.ThreadBeanProvider;
import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.Result;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
@@ -40,18 +38,28 @@
@RunWith(MockitoJUnitRunner.class)
public class BlockedThreadsCheckTest {
+ private static final String HEALTHCHECK_CONFIG_BODY_THRESHOLD =
+ "[healthcheck \"" + BLOCKEDTHREADS + "\"]\n" + " threshold = ";
+ private static final HealthCheckConfig CONFIG_THRESHOLD_25 =
+ new HealthCheckConfig(HEALTHCHECK_CONFIG_BODY_THRESHOLD + "25");
+ private static final HealthCheckConfig CONFIG_THRESHOLD_33 =
+ new HealthCheckConfig(HEALTHCHECK_CONFIG_BODY_THRESHOLD + "33");
+
@Mock BlockedThreadsCheck.ThreadBeanProvider threadBeanProviderMock;
@Mock ThreadMXBean beanMock;
+ private Injector testInjector;
+
@Before
public void setUp() {
when(threadBeanProviderMock.get()).thenReturn(beanMock);
+ testInjector = createTestInjector(HealthCheckConfig.DEFAULT_CONFIG);
}
@Test
public void shouldPassCheckWhenNoThreadsAreReturned() {
- BlockedThreadsCheck objectUnderTest = createCheck(HealthCheckConfig.DEFAULT_CONFIG);
+ BlockedThreadsCheck objectUnderTest = createCheck();
when(beanMock.getThreadInfo(null, 0)).thenReturn(new ThreadInfo[0]);
assertThat(objectUnderTest.run().result).isEqualTo(Result.PASSED);
}
@@ -88,18 +96,18 @@
public void shouldPassCheckWhenBlockedThreadsAreLessThenThreshold() {
int running = 3;
int blocked = 1;
- HealthCheckConfig config =
- new HealthCheckConfig("[healthcheck \"" + BLOCKEDTHREADS + "\"]\n" + " threshold = 25");
- mockThreadsAndCheckResult(running, blocked, Result.PASSED, config);
+ testInjector = createTestInjector(CONFIG_THRESHOLD_25);
+
+ mockThreadsAndCheckResult(running, blocked, Result.PASSED);
}
@Test
public void shouldFailCheckWhenBlockedThreadsAreAboveTheThreshold() {
int running = 1;
int blocked = 1;
- HealthCheckConfig config =
- new HealthCheckConfig("[healthcheck \"" + BLOCKEDTHREADS + "\"]\n" + " threshold = 33");
- mockThreadsAndCheckResult(running, blocked, Result.FAILED, config);
+ testInjector = createTestInjector(CONFIG_THRESHOLD_33);
+
+ mockThreadsAndCheckResult(running, blocked, Result.FAILED);
}
@Test
@@ -107,10 +115,9 @@
int running = 3;
int blocked = 1;
String prefix = "blocked-threads-prefix";
- HealthCheckConfig config =
- new HealthCheckConfig(
- "[healthcheck \"" + BLOCKEDTHREADS + "\"]\n" + " threshold = " + prefix + " = 25");
- mockThreadsAndCheckResult(running, blocked, Result.PASSED, prefix, config);
+ testInjector = createTestInjector(CONFIG_THRESHOLD_25);
+
+ mockThreadsAndCheckResult(running, blocked, Result.PASSED, prefix);
}
@Test
@@ -118,10 +125,9 @@
int running = 1;
int blocked = 1;
String prefix = "blocked-threads-prefix";
- HealthCheckConfig config =
- new HealthCheckConfig(
- "[healthcheck \"" + BLOCKEDTHREADS + "\"]\n" + " threshold = " + prefix + " = 33");
- mockThreadsAndCheckResult(running, blocked, Result.FAILED, prefix, config);
+ testInjector = createTestInjector(CONFIG_THRESHOLD_33);
+
+ mockThreadsAndCheckResult(running, blocked, Result.FAILED, prefix);
}
@Test
@@ -141,31 +147,27 @@
+ "\nthreshold = "
+ notBlockedPrefix
+ "=33");
+ testInjector = createTestInjector(config);
+
List<ThreadInfo> infos = new ArrayList<>(running + blocked + running);
infos.addAll(nCopies(running, mockInfo(Thread.State.RUNNABLE, blockedPrefix)));
infos.addAll(nCopies(blocked, mockInfo(Thread.State.BLOCKED, blockedPrefix)));
infos.addAll(nCopies(running, mockInfo(Thread.State.RUNNABLE, notBlockedPrefix)));
when(beanMock.getThreadInfo(null, 0)).thenReturn(infos.toArray(new ThreadInfo[infos.size()]));
- checkResult(Result.FAILED, config);
+ checkResult(Result.FAILED);
}
private void mockThreadsAndCheckResult(int running, int blocked, Result expected) {
- mockThreadsAndCheckResult(running, blocked, expected, HealthCheckConfig.DEFAULT_CONFIG);
+ mockThreadsAndCheckResult(running, blocked, expected, "some-prefix");
}
- private void mockThreadsAndCheckResult(
- int running, int blocked, Result expected, HealthCheckConfig config) {
- mockThreadsAndCheckResult(running, blocked, expected, "some-prefix", config);
- }
-
- private void mockThreadsAndCheckResult(
- int running, int blocked, Result expected, String prefix, HealthCheckConfig config) {
+ private void mockThreadsAndCheckResult(int running, int blocked, Result expected, String prefix) {
mockThreads(running, blocked, prefix);
- checkResult(expected, config);
+ checkResult(expected);
}
- private void checkResult(Result expected, HealthCheckConfig config) {
- BlockedThreadsCheck objectUnderTest = createCheck(config);
+ private void checkResult(Result expected) {
+ BlockedThreadsCheck objectUnderTest = createCheck();
assertThat(objectUnderTest.run().result).isEqualTo(expected);
}
@@ -183,8 +185,11 @@
return infoMock;
}
- private BlockedThreadsCheck createCheck(HealthCheckConfig config) {
- DummyHealthCheckMetricsFactory checkMetricsFactory = new DummyHealthCheckMetricsFactory();
+ private BlockedThreadsCheck createCheck() {
+ return testInjector.getInstance(BlockedThreadsCheck.class);
+ }
+
+ private Injector createTestInjector(HealthCheckConfig config) {
Injector injector =
Guice.createInjector(
new HealthCheckModule(),
@@ -192,15 +197,11 @@
@Override
protected void configure() {
bind(HealthCheckConfig.class).toInstance(config);
- bind(HealthCheckMetrics.Factory.class).toInstance(checkMetricsFactory);
+ bind(HealthCheckMetrics.Factory.class).to(DummyHealthCheckMetricsFactory.class);
+ bind(ThreadBeanProvider.class).toInstance(threadBeanProviderMock);
}
},
BlockedThreadsCheck.SUB_CHECKS);
- return new BlockedThreadsCheck(
- injector.getInstance(ListeningExecutorService.class),
- config,
- checkMetricsFactory,
- threadBeanProviderMock,
- Providers.of(injector.getInstance(BlockedThreadsConfigurator.class)));
+ return injector;
}
}