/* * Copyright (C) 2012-2015 DataStax 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. * See the License for the specific language governing permissions and * limitations under the License. */ package com.datastax.driver.core; import com.google.common.collect.Iterators; import org.assertj.core.api.AbstractAssert; import java.net.InetAddress; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; public class ClusterAssert extends AbstractAssert<ClusterAssert, Cluster> { protected ClusterAssert(Cluster actual) { super(actual, ClusterAssert.class); } public ClusterAssert usesControlHost(int node) { String expectedAddress = TestUtils.ipOfNode(node); Host controlHost = actual.manager.controlConnection.connectedHost(); assertThat(controlHost.getAddress().getHostAddress()).isEqualTo(expectedAddress); return this; } public ClusterAssert hasClosedControlConnection() { assertThat(actual.manager.controlConnection.isOpen()).isFalse(); return this; } public ClusterAssert hasOpenControlConnection() { assertThat(actual.manager.controlConnection.isOpen()).isTrue(); return this; } public HostAssert controlHost() { Host host = TestUtils.findOrWaitForControlConnection(actual, 10, TimeUnit.SECONDS); return new HostAssert(host, actual); } public HostAssert host(int hostNumber) { // Wait for the node to be added if it's not already known. // In 2.2+ C* does not send an added event until the node is ready so we wait a long time. Host host = TestUtils.findOrWaitForHost(actual, hostNumber, 60 + Cluster.NEW_NODE_DELAY_SECONDS, TimeUnit.SECONDS); return new HostAssert(host, actual); } public HostAssert host(String hostAddress) { Host host = TestUtils.findOrWaitForHost(actual, hostAddress, 60 + Cluster.NEW_NODE_DELAY_SECONDS, TimeUnit.SECONDS); return new HostAssert(host, actual); } public HostAssert host(InetAddress hostAddress) { return host(hostAddress.getHostAddress()); } /** * Asserts that {@link Cluster}'s {@link Host}s have valid {@link TokenRange}s with the given keyspace. * <p/> * Ensures that no ranges intersect and that they cover the entire ring. * * @param keyspace Keyspace to grab {@link TokenRange}s from. */ public ClusterAssert hasValidTokenRanges(String keyspace) { // Sort the token ranges so they are in order (needed for vnodes). Set<TokenRange> ranges = new TreeSet<TokenRange>(); for (Host host : actual.getMetadata().getAllHosts()) { ranges.addAll(actual.getMetadata().getTokenRanges(keyspace, host)); } return hasValidTokenRanges(ranges); } /** * Asserts that {@link Cluster}'s {@link Host}s have valid {@link TokenRange}s. * <p/> * Ensures that no ranges intersect and that they cover the entire ring. */ public ClusterAssert hasValidTokenRanges() { // Sort the token ranges so they are in order (needed for vnodes). Set<TokenRange> ranges = new TreeSet<TokenRange>(actual.getMetadata().getTokenRanges()); return hasValidTokenRanges(ranges); } /** * Asserts that given Set of {@link TokenRange}s are valid. * <p/> * Ensures that no ranges intersect and that they cover the entire ring. */ private ClusterAssert hasValidTokenRanges(Set<TokenRange> ranges) { // Ensure no ranges intersect. Iterator<TokenRange> it = ranges.iterator(); while (it.hasNext()) { TokenRange range = it.next(); Assertions.assertThat(range).doesNotIntersect(Iterators.toArray(it, TokenRange.class)); } // Ensure the defined ranges cover the entire ring. it = ranges.iterator(); TokenRange mergedRange = it.next(); while (it.hasNext()) { TokenRange next = it.next(); mergedRange = mergedRange.mergeWith(next); } boolean isFullRing = mergedRange.getStart().equals(mergedRange.getEnd()) && !mergedRange.isEmpty(); assertThat(isFullRing) .as("Ring is not fully defined for Cluster.") .isTrue(); return this; } }