Commit 6f08e970 authored by Stephane Nicoll's avatar Stephane Nicoll

Polish "Improve Cassandra health indicator with more robust mechanism"

See gh-23041
parent 8e5a041b
...@@ -16,7 +16,10 @@ ...@@ -16,7 +16,10 @@
package org.springframework.boot.actuate.cassandra; package org.springframework.boot.actuate.cassandra;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
...@@ -34,15 +37,13 @@ import org.springframework.boot.actuate.health.Status; ...@@ -34,15 +37,13 @@ import org.springframework.boot.actuate.health.Status;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.BDDMockito.when;
/** /**
* Tests for {@link CassandraDriverHealthIndicator}. * Tests for {@link CassandraDriverHealthIndicator}.
* *
* @author Alexandre Dutra * @author Alexandre Dutra
* @author Tomasz Lelek * @author Stephane Nicoll
* @since 2.4.0
*/ */
class CassandraDriverHealthIndicatorTests { class CassandraDriverHealthIndicatorTests {
...@@ -52,112 +53,70 @@ class CassandraDriverHealthIndicatorTests { ...@@ -52,112 +53,70 @@ class CassandraDriverHealthIndicatorTests {
} }
@Test @Test
void oneHealthyNodeShouldReturnUp() { void healthWithOneHealthyNodeShouldReturnUp() {
CqlSession session = mock(CqlSession.class); CqlSession session = mockCqlSessionWithNodeState(NodeState.UP);
Metadata metadata = mock(Metadata.class);
Node healthyNode = mock(Node.class);
given(healthyNode.getState()).willReturn(NodeState.UP);
given(session.getMetadata()).willReturn(metadata);
given(metadata.getNodes()).willReturn(createNodesMap(healthyNode));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
} }
@Test @Test
void oneUnhealthyNodeShouldReturnDown() { void healthWithOneUnhealthyNodeShouldReturnDown() {
CqlSession session = mock(CqlSession.class); CqlSession session = mockCqlSessionWithNodeState(NodeState.DOWN);
Metadata metadata = mock(Metadata.class);
Node unhealthyNode = mock(Node.class);
given(unhealthyNode.getState()).willReturn(NodeState.DOWN);
given(session.getMetadata()).willReturn(metadata);
given(metadata.getNodes()).willReturn(createNodesMap(unhealthyNode));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getStatus()).isEqualTo(Status.DOWN);
} }
@Test @Test
void oneUnknownNodeShouldReturnDown() { void healthWithOneUnknownNodeShouldReturnDown() {
CqlSession session = mock(CqlSession.class); CqlSession session = mockCqlSessionWithNodeState(NodeState.UNKNOWN);
Metadata metadata = mock(Metadata.class);
Node unknownNode = mock(Node.class);
given(unknownNode.getState()).willReturn(NodeState.UNKNOWN);
given(session.getMetadata()).willReturn(metadata);
given(metadata.getNodes()).willReturn(createNodesMap(unknownNode));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getStatus()).isEqualTo(Status.DOWN);
} }
@Test @Test
void oneForcedDownNodeShouldReturnDown() { void healthWithOneForcedDownNodeShouldReturnDown() {
CqlSession session = mock(CqlSession.class); CqlSession session = mockCqlSessionWithNodeState(NodeState.FORCED_DOWN);
Metadata metadata = mock(Metadata.class);
Node forcedDownNode = mock(Node.class);
given(forcedDownNode.getState()).willReturn(NodeState.FORCED_DOWN);
given(session.getMetadata()).willReturn(metadata);
given(metadata.getNodes()).willReturn(createNodesMap(forcedDownNode));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getStatus()).isEqualTo(Status.DOWN);
} }
@Test @Test
void oneHealthyNodeAndOneUnhealthyNodeShouldReturnUp() { void healthWithOneHealthyNodeAndOneUnhealthyNodeShouldReturnUp() {
CqlSession session = mock(CqlSession.class); CqlSession session = mockCqlSessionWithNodeState(NodeState.UP, NodeState.DOWN);
Metadata metadata = mock(Metadata.class);
Node healthyNode = mock(Node.class);
Node unhealthyNode = mock(Node.class);
given(healthyNode.getState()).willReturn(NodeState.UP);
given(unhealthyNode.getState()).willReturn(NodeState.DOWN);
given(session.getMetadata()).willReturn(metadata);
given(metadata.getNodes()).willReturn(createNodesMap(healthyNode, unhealthyNode));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
} }
@Test @Test
void oneHealthyNodeAndOneUnknownNodeShouldReturnUp() { void healthWithOneHealthyNodeAndOneUnknownNodeShouldReturnUp() {
CqlSession session = mock(CqlSession.class); CqlSession session = mockCqlSessionWithNodeState(NodeState.UP, NodeState.UNKNOWN);
Metadata metadata = mock(Metadata.class);
Node healthyNode = mock(Node.class);
Node unknownNode = mock(Node.class);
given(healthyNode.getState()).willReturn(NodeState.UP);
given(unknownNode.getState()).willReturn(NodeState.UNKNOWN);
given(session.getMetadata()).willReturn(metadata);
given(metadata.getNodes()).willReturn(createNodesMap(healthyNode, unknownNode));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
} }
@Test @Test
void oneHealthyNodeAndOneForcedDownNodeShouldReturnUp() { void healthWithOneHealthyNodeAndOneForcedDownNodeShouldReturnUp() {
CqlSession session = mock(CqlSession.class); CqlSession session = mockCqlSessionWithNodeState(NodeState.UP, NodeState.FORCED_DOWN);
Metadata metadata = mock(Metadata.class);
Node healthyNode = mock(Node.class);
Node forcedDownNode = mock(Node.class);
given(healthyNode.getState()).willReturn(NodeState.UP);
given(forcedDownNode.getState()).willReturn(NodeState.FORCED_DOWN);
given(session.getMetadata()).willReturn(metadata);
given(metadata.getNodes()).willReturn(createNodesMap(healthyNode, forcedDownNode));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
} }
@Test @Test
void addVersionToDetailsIfReportedNotNull() { void healthWithNodeVersionShouldAddVersionDetail() {
CqlSession session = mock(CqlSession.class); CqlSession session = mock(CqlSession.class);
Metadata metadata = mock(Metadata.class); Metadata metadata = mock(Metadata.class);
when(session.getMetadata()).thenReturn(metadata); given(session.getMetadata()).willReturn(metadata);
Node node = mock(Node.class); Node node = mock(Node.class);
when(node.getState()).thenReturn(NodeState.UP); given(node.getState()).willReturn(NodeState.UP);
when(node.getCassandraVersion()).thenReturn(Version.V4_0_0); given(node.getCassandraVersion()).willReturn(Version.V4_0_0);
when(metadata.getNodes()).thenReturn(createNodesMap(node)); given(metadata.getNodes()).willReturn(createNodesWithRandomUUID(Collections.singletonList(node)));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
...@@ -165,14 +124,8 @@ class CassandraDriverHealthIndicatorTests { ...@@ -165,14 +124,8 @@ class CassandraDriverHealthIndicatorTests {
} }
@Test @Test
void doNotAddVersionToDetailsIfReportedNull() { void healthWithoutNodeVersionShouldNotAddVersionDetail() {
CqlSession session = mock(CqlSession.class); CqlSession session = mockCqlSessionWithNodeState(NodeState.UP);
Metadata metadata = mock(Metadata.class);
when(session.getMetadata()).thenReturn(metadata);
Node node = mock(Node.class);
when(node.getState()).thenReturn(NodeState.UP);
when(metadata.getNodes()).thenReturn(createNodesMap(node));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
...@@ -180,7 +133,7 @@ class CassandraDriverHealthIndicatorTests { ...@@ -180,7 +133,7 @@ class CassandraDriverHealthIndicatorTests {
} }
@Test @Test
void healthWithCassandraDown() { void healthWithcassandraDownShouldReturnDown() {
CqlSession session = mock(CqlSession.class); CqlSession session = mock(CqlSession.class);
given(session.getMetadata()).willThrow(new DriverTimeoutException("Test Exception")); given(session.getMetadata()).willThrow(new DriverTimeoutException("Test Exception"));
CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session); CassandraDriverHealthIndicator healthIndicator = new CassandraDriverHealthIndicator(session);
...@@ -190,12 +143,24 @@ class CassandraDriverHealthIndicatorTests { ...@@ -190,12 +143,24 @@ class CassandraDriverHealthIndicatorTests {
.isEqualTo(DriverTimeoutException.class.getName() + ": Test Exception"); .isEqualTo(DriverTimeoutException.class.getName() + ": Test Exception");
} }
private static Map<UUID, Node> createNodesMap(Node... nodes) { private CqlSession mockCqlSessionWithNodeState(NodeState... nodeStates) {
Map<UUID, Node> nodesMap = new HashMap<>(); CqlSession session = mock(CqlSession.class);
for (Node n : nodes) { Metadata metadata = mock(Metadata.class);
nodesMap.put(UUID.randomUUID(), n); List<Node> nodes = new ArrayList<>();
for (NodeState nodeState : nodeStates) {
Node node = mock(Node.class);
given(node.getState()).willReturn(nodeState);
nodes.add(node);
} }
return nodesMap; given(session.getMetadata()).willReturn(metadata);
given(metadata.getNodes()).willReturn(createNodesWithRandomUUID(nodes));
return session;
}
private Map<UUID, Node> createNodesWithRandomUUID(List<Node> nodes) {
Map<UUID, Node> indexedNodes = new HashMap<>();
nodes.forEach((node) -> indexedNodes.put(UUID.randomUUID(), node));
return indexedNodes;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment