/*
* 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.datastax.driver.core.Host.State;
import com.datastax.driver.core.Host.StateListener;
import com.datastax.driver.core.policies.LoadBalancingPolicy;
import org.assertj.core.api.AbstractAssert;
import java.net.InetAddress;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static com.datastax.driver.core.ConditionChecker.check;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class HostAssert extends AbstractAssert<HostAssert, Host> {
private final Cluster cluster;
protected HostAssert(Host host) {
this(host, null);
}
protected HostAssert(Host host, Cluster cluster) {
super(host, HostAssert.class);
this.cluster = cluster;
}
public HostAssert hasState(Host.State expected) {
assertThat(actual.state).isEqualTo(expected);
return this;
}
public HostAssert isUp() {
assertThat(actual.isUp()).isTrue();
return this;
}
public HostAssert isDown() {
assertThat(actual.isUp()).isFalse();
return this;
}
public HostAssert isAtDistance(HostDistance expected) {
LoadBalancingPolicy loadBalancingPolicy = cluster.manager.loadBalancingPolicy();
assertThat(loadBalancingPolicy.distance(actual)).isEqualTo(expected);
return this;
}
public HostAssert isReconnectingFromDown() {
assertThat(actual.getReconnectionAttemptFuture() != null && !actual.getReconnectionAttemptFuture().isDone())
.isTrue();
return this;
}
public HostAssert isInDatacenter(String datacenter) {
assertThat(actual.getDatacenter()).isEqualTo(datacenter);
return this;
}
public HostAssert isNotReconnectingFromDown() {
// Ensure that host is not attempting a reconnect. Because of JAVA-970 we cannot
// be sure that there is a race and another pool is created before the host is marked down so we
// check to see it stops after 30 seconds.
// TODO: Change this to check only once if JAVA-970 is fixed.
check().before(30, TimeUnit.SECONDS).that(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
// Whether or not host is down and reconnection attempt is in progress.
return actual.getReconnectionAttemptFuture() != null && !actual.getReconnectionAttemptFuture().isDone();
}
}).becomesFalse();
return this.isDown();
}
public HostAssert comesUpWithin(long duration, TimeUnit unit) {
final CountDownLatch upSignal = new CountDownLatch(1);
StateListener upListener = new StateListenerBase() {
@Override
public void onUp(Host host) {
upSignal.countDown();
}
@Override
public void onAdd(Host host) {
// Special case, cassandra will sometimes not send an 'UP' topology change event
// for a new node, because of this we also listen for add events.
upSignal.countDown();
}
};
cluster.register(upListener);
try {
// If the host is already up or if we receive the UP signal within given time
if (actual.isUp() || upSignal.await(duration, unit)) {
return this;
}
} catch (InterruptedException e) {
fail("Got interrupted while waiting for host to come up");
} finally {
cluster.unregister(upListener);
}
fail(actual + " did not come up within " + duration + " " + unit);
return this;
}
public HostAssert goesDownWithin(long duration, TimeUnit unit) {
final CountDownLatch downSignal = new CountDownLatch(1);
StateListener upListener = new StateListenerBase() {
@Override
public void onDown(Host host) {
downSignal.countDown();
}
};
cluster.register(upListener);
try {
// If the host is already down or if we receive the DOWN signal within given time
if (actual.state == State.DOWN || downSignal.await(duration, unit))
return this;
} catch (InterruptedException e) {
fail("Got interrupted while waiting for host to go down");
} finally {
cluster.unregister(upListener);
}
fail(actual + " did not go down within " + duration + " " + unit);
return this;
}
@SuppressWarnings("deprecation")
public HostAssert hasWorkload(String workload) {
assertThat(actual.getDseWorkload()).isNotNull().isEqualTo(workload);
return this;
}
@SuppressWarnings("deprecation")
public HostAssert hasNoWorkload() {
assertThat(actual.getDseWorkload()).isNull();
return this;
}
@SuppressWarnings("deprecation")
public HostAssert hasDseVersion(VersionNumber versionNumber) {
assertThat(actual.getDseVersion()).isNotNull().isEqualTo(versionNumber);
return this;
}
@SuppressWarnings("deprecation")
public HostAssert hasNoDseVersion() {
assertThat(actual.getDseVersion()).isNull();
return this;
}
@SuppressWarnings("deprecation")
public HostAssert hasDseGraph() {
assertThat(actual.isDseGraphEnabled()).isTrue();
return this;
}
@SuppressWarnings("deprecation")
public HostAssert hasNoDseGraph() {
assertThat(actual.isDseGraphEnabled()).isFalse();
return this;
}
public HostAssert hasListenAddress(InetAddress address) {
assertThat(actual.getListenAddress()).isNotNull().isEqualTo(address);
return this;
}
public HostAssert hasNoListenAddress() {
assertThat(actual.getListenAddress()).isNull();
return this;
}
public HostAssert hasBroadcastAddress(InetAddress address) {
assertThat(actual.getBroadcastAddress()).isNotNull().isEqualTo(address);
return this;
}
public HostAssert hasNoBroadcastAddress() {
assertThat(actual.getBroadcastAddress()).isNull();
return this;
}
}