package org.ovirt.engine.core.bll.validator;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.ovirt.engine.core.bll.validator.ValidationResultMatchers.failsWith;
import static org.ovirt.engine.core.bll.validator.ValidationResultMatchers.isValid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.ovirt.engine.core.bll.ValidationResult;
import org.ovirt.engine.core.bll.validator.gluster.GlusterBrickValidator;
import org.ovirt.engine.core.common.businessentities.gluster.AccessProtocol;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterStatus;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeType;
import org.ovirt.engine.core.common.businessentities.gluster.TransportType;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.compat.Guid;
public class GlusterBrickValidatorTest {
private GlusterBrickValidator brickValidator = new GlusterBrickValidator();
private final Guid volumeId1 = new Guid("8bc6f108-c0ef-43ab-ba20-ec41107220f5");
private GlusterVolumeEntity getDistributedVolume(Guid volumeId, int brickCount) {
GlusterVolumeEntity volumeEntity = new GlusterVolumeEntity();
volumeEntity.setId(volumeId);
volumeEntity.setName("test-vol");
volumeEntity.addAccessProtocol(AccessProtocol.GLUSTER);
volumeEntity.addTransportType(TransportType.TCP);
volumeEntity.setVolumeType(GlusterVolumeType.DISTRIBUTE);
volumeEntity.setBricks(getBricks(volumeId, brickCount));
return volumeEntity;
}
private GlusterVolumeEntity getDistributedReplicatedVolume(Guid volumeId, int brickCount, int replicaCount) {
GlusterVolumeEntity volumeEntity = new GlusterVolumeEntity();
volumeEntity.setId(volumeId);
volumeEntity.setName("test-vol");
volumeEntity.addAccessProtocol(AccessProtocol.GLUSTER);
volumeEntity.addTransportType(TransportType.TCP);
volumeEntity.setVolumeType(GlusterVolumeType.DISTRIBUTED_REPLICATE);
volumeEntity.setBricks(getBricks(volumeId, brickCount));
volumeEntity.setReplicaCount(replicaCount);
return volumeEntity;
}
private List<GlusterBrickEntity> getBricks(Guid volumeId, int max) {
List<GlusterBrickEntity> bricks = new ArrayList<>();
for (Integer i = 0; i < max; i++) {
GlusterBrickEntity brick = new GlusterBrickEntity();
brick.setVolumeId(volumeId);
brick.setServerName("server1");
brick.setStatus(GlusterStatus.UP);
brick.setBrickDirectory("/tmp/s" + i.toString());
bricks.add(brick);
brick.setId(Guid.newGuid());
}
return bricks;
}
@Test
public void canRebalanceOnDistributedVolume() {
GlusterVolumeEntity volumeEntity = getDistributedVolume(volumeId1, 5);
ValidationResult validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, isValid());
}
@Test
public void canRebalanceOnDistributedVolumeWithBricksDown() {
GlusterVolumeEntity volumeEntity = getDistributedVolume(volumeId1, 5);
// One Brick Down
volumeEntity.getBricks().get(3).setStatus(GlusterStatus.DOWN);
ValidationResult validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, not(isValid()));
// Two Bricks Down
volumeEntity.getBricks().get(4).setStatus(GlusterStatus.DOWN);
validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, not(isValid()));
// One Brick Down
volumeEntity.getBricks().get(3).setStatus(GlusterStatus.UP);
validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, not(isValid()));
}
@Test
public void canRebalanceOnDistributeReplicateVolume() {
GlusterVolumeEntity volumeEntity = getDistributedReplicatedVolume(volumeId1, 12, 4);
ValidationResult validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, isValid());
}
@Test
public void canRebalanceOnDistributeReplicateVolumeWithFewBrickDown() {
GlusterVolumeEntity volumeEntity = getDistributedReplicatedVolume(volumeId1, 12, 4);
volumeEntity.getBricks().get(0).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(1).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(2).setStatus(GlusterStatus.DOWN);
ValidationResult validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, isValid());
volumeEntity.getBricks().get(4).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(5).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(6).setStatus(GlusterStatus.DOWN);
validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, isValid());
}
@Test
public void canRebalanceOnDistributeReplicateVolumeWithOneReplicaPairDown() {
GlusterVolumeEntity volumeEntity = getDistributedReplicatedVolume(volumeId1, 12, 4);
volumeEntity.getBricks().get(0).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(1).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(2).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(3).setStatus(GlusterStatus.DOWN);
ValidationResult validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, not(isValid()));
}
@Test
public void canRebalanceOnDistributeReplicateVolumeWithTwoReplicaPairDown() {
GlusterVolumeEntity volumeEntity = getDistributedReplicatedVolume(volumeId1, 12, 4);
volumeEntity.getBricks().get(0).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(2).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(3).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(4).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(5).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(6).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(7).setStatus(GlusterStatus.DOWN);
volumeEntity.getBricks().get(8).setStatus(GlusterStatus.DOWN);
ValidationResult validationResult = brickValidator.canRebalance(volumeEntity);
assertThat(validationResult, not(isValid()));
}
@Test
public void canRemoveBrickEmptyList() {
ValidationResult validationResult =
brickValidator.canRemoveBrick(Collections.emptyList(),
getDistributedVolume(volumeId1, 1),
3,
false);
assertThat(validationResult, failsWith(EngineMessage.ACTION_TYPE_FAILED_BRICKS_REQUIRED));
}
@Test
public void canRemoveLastBrick() {
GlusterVolumeEntity volumeEntity = getDistributedVolume(volumeId1, 1);
ValidationResult validationResult =
brickValidator.canRemoveBrick(volumeEntity.getBricks(), volumeEntity, 1, false);
assertThat(validationResult, failsWith(EngineMessage.ACTION_TYPE_FAILED_CAN_NOT_REMOVE_ALL_BRICKS_FROM_VOLUME));
}
@Test
public void canRemoveAllBricksFromSubVolume() {
GlusterVolumeEntity volumeEntity = getDistributedReplicatedVolume(volumeId1, 9, 3);
List<GlusterBrickEntity> bricksToRemove = new ArrayList<>();
bricksToRemove.add(volumeEntity.getBricks().get(6));
bricksToRemove.add(volumeEntity.getBricks().get(7));
bricksToRemove.add(volumeEntity.getBricks().get(8));
ValidationResult validationResult =
brickValidator.canRemoveBrick(bricksToRemove, volumeEntity, 3, false);
assertThat(validationResult, isValid());
}
@Test
public void canRemoveBrickIfSomeBricksAreDown() {
GlusterVolumeEntity volumeEntity = getDistributedVolume(volumeId1, 4);
List<GlusterBrickEntity> bricksToRemove = new ArrayList<>();
bricksToRemove.add(volumeEntity.getBricks().get(1));
volumeEntity.getBricks().get(0).setStatus(GlusterStatus.DOWN);
ValidationResult validationResult =
brickValidator.canRemoveBrick(bricksToRemove, volumeEntity, 1, false);
assertThat(validationResult, failsWith(EngineMessage.ACTION_TYPE_FAILED_ONE_OR_MORE_BRICKS_ARE_DOWN));
}
@Test
public void canRemoveWithOutforceAndReduceReplicaCount() {
GlusterVolumeEntity volumeEntity = getDistributedReplicatedVolume(volumeId1, 12, 4);
List<GlusterBrickEntity> bricksToRemove = new ArrayList<>();
bricksToRemove.add(volumeEntity.getBricks().get(0));
bricksToRemove.add(volumeEntity.getBricks().get(4));
bricksToRemove.add(volumeEntity.getBricks().get(8));
ValidationResult validationResult =
brickValidator.canRemoveBrick(bricksToRemove, volumeEntity, 3, false);
assertThat(validationResult,
failsWith(EngineMessage.ACTION_TYPE_FAILED_CAN_NOT_REDUCE_REPLICA_COUNT_WITH_DATA_MIGRATION));
}
@Test
public void canRemoveBrickReduceReplicaMoreThanOne() {
GlusterVolumeEntity volumeEntity = getDistributedReplicatedVolume(volumeId1, 12, 4);
List<GlusterBrickEntity> bricksToRemove = new ArrayList<>();
bricksToRemove.add(volumeEntity.getBricks().get(0));
bricksToRemove.add(volumeEntity.getBricks().get(4));
bricksToRemove.add(volumeEntity.getBricks().get(8));
bricksToRemove.add(volumeEntity.getBricks().get(1));
bricksToRemove.add(volumeEntity.getBricks().get(5));
bricksToRemove.add(volumeEntity.getBricks().get(9));
ValidationResult validationResult =
brickValidator.canRemoveBrick(bricksToRemove, volumeEntity, 2, false);
assertThat(validationResult,
failsWith(EngineMessage.ACTION_TYPE_FAILED_CAN_NOT_REDUCE_REPLICA_COUNT_MORE_THAN_ONE));
}
@Test
public void canRemoveIncreaseReplica() {
GlusterVolumeEntity volumeEntity = getDistributedReplicatedVolume(volumeId1, 12, 4);
List<GlusterBrickEntity> bricksToRemove = new ArrayList<>();
bricksToRemove.add(volumeEntity.getBricks().get(0));
ValidationResult validationResult =
brickValidator.canRemoveBrick(bricksToRemove, volumeEntity, 5, false);
assertThat(validationResult, failsWith(EngineMessage.ACTION_TYPE_FAILED_CAN_NOT_INCREASE_REPLICA_COUNT));
}
@Test
public void canRemoveNonExistentBrick() {
GlusterVolumeEntity volumeEntity = getDistributedVolume(volumeId1, 4);
List<GlusterBrickEntity> bricksToRemove = new ArrayList<>();
bricksToRemove.addAll(getBricks(volumeEntity.getId(), 1));
bricksToRemove.get(0).setBrickDirectory("NewServer:/NewExport");
ValidationResult validationResult =
brickValidator.canRemoveBrick(bricksToRemove, volumeEntity, 1, false);
assertThat(validationResult, failsWith(EngineMessage.ACTION_TYPE_FAILED_GLUSTER_BRICK_INVALID));
}
@Test
public void canRemoveBrickUpdatesBrickDetalis() {
GlusterVolumeEntity volumeEntity = getDistributedVolume(volumeId1, 4);
List<GlusterBrickEntity> bricksToRemove = new ArrayList<>();
bricksToRemove.addAll(getBricks(volumeEntity.getId(), 1));
bricksToRemove.get(0).setId(volumeEntity.getBricks().get(2).getId());
bricksToRemove.get(0).setServerName(null);
bricksToRemove.get(0).setBrickDirectory(null);
ValidationResult validationResult =
brickValidator.canRemoveBrick(bricksToRemove, volumeEntity, 1, false);
assertThat(validationResult, isValid());
assertThat(bricksToRemove.get(0).getServerName(), notNullValue());
assertThat(bricksToRemove.get(0).getBrickDirectory(), notNullValue());
}
}