From b286c5c6f061a865c7df04504f1787fb36573882 Mon Sep 17 00:00:00 2001 From: John Blum Date: Wed, 19 Sep 2018 18:07:02 -0700 Subject: [PATCH] Add Unit Tests for GeodePoolsHealthIndicator. --- .../actuate/GeodePoolsHealthIndicator.java | 17 +- .../GeodePoolsHealthIndicatorUnitTests.java | 164 ++++++++++++++++++ 2 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 spring-geode-actuator/src/test/java/org/springframework/geode/boot/actuate/GeodePoolsHealthIndicatorUnitTests.java diff --git a/spring-geode-actuator/src/main/java/org/springframework/geode/boot/actuate/GeodePoolsHealthIndicator.java b/spring-geode-actuator/src/main/java/org/springframework/geode/boot/actuate/GeodePoolsHealthIndicator.java index 3094690d..d585a5e1 100644 --- a/spring-geode-actuator/src/main/java/org/springframework/geode/boot/actuate/GeodePoolsHealthIndicator.java +++ b/spring-geode-actuator/src/main/java/org/springframework/geode/boot/actuate/GeodePoolsHealthIndicator.java @@ -21,6 +21,7 @@ import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeMap; import java.net.InetSocketAddress; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -74,7 +75,11 @@ public class GeodePoolsHealthIndicator extends AbstractGeodeHealthIndicator { if (getGemFireCache().filter(CacheUtils::isClient).isPresent()) { - nullSafeMap(PoolManager.getAll()).values().stream() + Map pools = nullSafeMap(findAllPools()); + + builder.withDetail("geode.pool.count", pools.size()); + + pools.values().stream() .filter(Objects::nonNull) .forEach(pool -> { @@ -97,12 +102,12 @@ public class GeodePoolsHealthIndicator extends AbstractGeodeHealthIndicator { .withDetail(poolKey(poolName, "server-group"), pool.getServerGroup()) .withDetail(poolKey(poolName, "servers"), toCommaDelimitedHostAndPortsString(pool.getServers())) .withDetail(poolKey(poolName, "socket-buffer-size"), pool.getSocketBufferSize()) - .withDetail(poolKey(poolName, "statistics-interval"), pool.getStatisticInterval()) + .withDetail(poolKey(poolName, "statistic-interval"), pool.getStatisticInterval()) .withDetail(poolKey(poolName, "subscription-ack-interval"), pool.getSubscriptionAckInterval()) .withDetail(poolKey(poolName, "subscription-enabled"), toYesNoString(pool.getSubscriptionEnabled())) - .withDetail(poolKey(poolName, "subscription-messaging-tracking-timeout"), pool.getSubscriptionMessageTrackingTimeout()) + .withDetail(poolKey(poolName, "subscription-message-tracking-timeout"), pool.getSubscriptionMessageTrackingTimeout()) .withDetail(poolKey(poolName, "subscription-redundancy"), pool.getSubscriptionRedundancy()) - .withDetail(poolKey(poolName, "thread-local-connections"), pool.getThreadLocalConnections()); + .withDetail(poolKey(poolName, "thread-local-connections"), toYesNoString(pool.getThreadLocalConnections())); }); builder.up(); @@ -113,6 +118,10 @@ public class GeodePoolsHealthIndicator extends AbstractGeodeHealthIndicator { builder.unknown(); } + Map findAllPools() { + return PoolManager.getAll(); + } + private String poolKey(String poolName, String suffix) { return String.format("geode.pool.%1$s.%2$s", poolName, suffix); } diff --git a/spring-geode-actuator/src/test/java/org/springframework/geode/boot/actuate/GeodePoolsHealthIndicatorUnitTests.java b/spring-geode-actuator/src/test/java/org/springframework/geode/boot/actuate/GeodePoolsHealthIndicatorUnitTests.java new file mode 100644 index 00000000..9d12ecfc --- /dev/null +++ b/spring-geode-actuator/src/test/java/org/springframework/geode/boot/actuate/GeodePoolsHealthIndicatorUnitTests.java @@ -0,0 +1,164 @@ +/* + * Copyright 2018 the original author or authors. + * + * 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. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package org.springframework.geode.boot.actuate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.net.InetSocketAddress; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.GemFireCache; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.Pool; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.Status; +import org.springframework.data.gemfire.tests.mock.PoolMockObjects; + +/** + * Unit tests for {@link GeodePoolsHealthIndicator}. + * + * @author John Blum + * @see org.junit.Test + * @see org.mockito.Mock + * @see org.mockito.Mockito + * @see org.mockito.junit.MockitoJUnitRunner + * @see org.apache.geode.cache.Cache + * @see org.apache.geode.cache.GemFireCache + * @see org.apache.geode.cache.client.ClientCache + * @see org.apache.geode.cache.client.Pool + * @see org.springframework.boot.actuate.health.Health + * @see org.springframework.boot.actuate.health.HealthIndicator + * @see org.springframework.data.gemfire.tests.mock.PoolMockObjects + * @see org.springframework.geode.boot.actuate.GeodePoolsHealthIndicator + * @since 1.0.0 + */ +@RunWith(MockitoJUnitRunner.class) +public class GeodePoolsHealthIndicatorUnitTests { + + @Mock + private ClientCache mockClientCache; + + private GeodePoolsHealthIndicator poolsHealthIndicator; + + @Before + public void setup() { + this.poolsHealthIndicator = spy(new GeodePoolsHealthIndicator(this.mockClientCache)); + } + + private InetSocketAddress testSocketAddress(String hostname, int port) { + return new InetSocketAddress(hostname, port); + } + + @Test + public void healthCheckCapturesDetails() throws Exception { + + List mockLocators = + Arrays.asList(testSocketAddress("mailbox", 1234), + testSocketAddress("skullbox", 6789)); + + Pool mockPool = PoolMockObjects.mockPool("MockPool", false, 5000, + 60000L, 1000, mockLocators, 500, 50, + true, mockLocators.subList(0, 1), 75, 15000L, + true, null, 10000, 2, "TestGroup", + Collections.emptyList(), 65536, 30000, 5000, + 10000, true, 5000, + 2, 8, false); + + when(this.poolsHealthIndicator.findAllPools()).thenReturn(Collections.singletonMap("MockPool", mockPool)); + + Health.Builder builder = new Health.Builder(); + + this.poolsHealthIndicator.doHealthCheck(builder); + + Health health = builder.build(); + + assertThat(health).isNotNull(); + assertThat(health.getStatus()).isEqualTo(Status.UP); + + Map healthDetails = health.getDetails(); + + assertThat(healthDetails).isNotNull(); + assertThat(healthDetails).isNotEmpty(); + assertThat(healthDetails).containsEntry("geode.pool.count", 1); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.destroyed", "No"); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.free-connection-timeout", 5000); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.idle-timeout", 60000L); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.load-conditioning-interval", 1000); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.locators", "mailbox:1234,skullbox:6789"); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.max-connections", 500); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.min-connections", 50); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.multi-user-authentication", "Yes"); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.online-locators", "mailbox:1234"); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.pending-event-count", 75); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.ping-interval", 15000L); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.pr-single-hop-enabled", "Yes"); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.read-timeout", 10000); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.retry-attempts", 2); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.server-group", "TestGroup"); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.servers", ""); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.socket-buffer-size", 65536); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.statistic-interval", 5000); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.subscription-ack-interval", 10000); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.subscription-enabled", "Yes"); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.subscription-message-tracking-timeout", 5000); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.subscription-redundancy", 2); + assertThat(healthDetails).containsEntry("geode.pool.MockPool.thread-local-connections", "No"); + + verify(this.poolsHealthIndicator, times(1)).findAllPools(); + } + + public void testHealthCheckFailsWithIvalidGemFireCache(GemFireCache gemfireCache) throws Exception { + + GeodePoolsHealthIndicator healthIndicator = gemfireCache != null + ? new GeodePoolsHealthIndicator(gemfireCache) + : new GeodePoolsHealthIndicator(); + + Health.Builder builder = new Health.Builder(); + + healthIndicator.doHealthCheck(builder); + + Health health = builder.build(); + + assertThat(health).isNotNull(); + assertThat(health.getDetails()).isEmpty(); + assertThat(health.getStatus()).isEqualTo(Status.UNKNOWN); + } + + @Test + public void healthCheckFailsWhenGemFireCacheIsNotClientCache() throws Exception { + testHealthCheckFailsWithIvalidGemFireCache(mock(Cache.class)); + } + + @Test + public void healthCheckFailsWhenGemFireCacheIsNotPresent() throws Exception { + testHealthCheckFailsWithIvalidGemFireCache(null); + } +}