package org.ovirt.engine.core.bll.gluster; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig; import java.util.ArrayList; import java.util.List; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.ovirt.engine.core.bll.BaseCommandTest; import org.ovirt.engine.core.bll.ValidateTestUtils; import org.ovirt.engine.core.common.action.gluster.CreateGlusterVolumeParameters; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.VdsStatic; 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.config.ConfigValues; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.Version; import org.ovirt.engine.core.dao.ClusterDao; import org.ovirt.engine.core.dao.VdsStaticDao; import org.ovirt.engine.core.dao.gluster.GlusterBrickDao; import org.ovirt.engine.core.dao.gluster.GlusterVolumeDao; import org.ovirt.engine.core.dao.network.InterfaceDao; import org.ovirt.engine.core.dao.network.NetworkDao; import org.ovirt.engine.core.utils.MockConfigRule; public class CreateGlusterVolumeCommandTest extends BaseCommandTest { @Mock GlusterVolumeDao volumeDao; @Mock GlusterBrickDao brickDao; @Mock VdsStaticDao vdsStaticDao; @Mock ClusterDao clusterDao; @Mock NetworkDao networkDao; @Mock InterfaceDao interfaceDao; private static final String serverName = "myhost"; private static final Guid clusterId = new Guid("c0dd8ca3-95dd-44ad-a88a-440a6e3d8106"); private static final Guid serverId = new Guid("d7f10a21-bbf2-4ffd-aab6-4da0b3b2ccec"); @Spy @InjectMocks private CreateGlusterVolumeCommand cmd = createTestCommand(getVolume(2, false)); @ClassRule public static MockConfigRule mcr = new MockConfigRule( mockConfig(ConfigValues.GlusterSupportArbiterVolume, Version.v4_0, false), mockConfig(ConfigValues.GlusterSupportArbiterVolume, Version.v4_1, true) ); private CreateGlusterVolumeCommand createTestCommand(GlusterVolumeEntity volumeEntity) { CreateGlusterVolumeParameters parameters = new CreateGlusterVolumeParameters(volumeEntity); return new CreateGlusterVolumeCommand(parameters, null); } private void setVolume(GlusterVolumeEntity volumeEntity) { cmd.getParameters().setVolume(volumeEntity); cmd.setGlusterVolumeId(volumeEntity.getId()); } private VDS getVds(VDSStatus status) { VDS vds = new VDS(); vds.setId(Guid.newGuid()); vds.setVdsName("gfs1"); vds.setClusterId(clusterId); vds.setStatus(status); return vds; } private VdsStatic getVdsStatic() { VdsStatic vds = new VdsStatic(); vds.setClusterId(clusterId); vds.setHostName(serverName); return vds; } private Cluster getCluster(boolean glusterEnabled, Version clusterVersion) { Cluster cluster = new Cluster(); cluster.setId(clusterId); cluster.setCompatibilityVersion(clusterVersion); cluster.setVirtService(false); cluster.setGlusterService(glusterEnabled); return cluster; } @Before public void prepareMocks() { doReturn(getVds(VDSStatus.Up)).when(cmd).getUpServer(); doReturn(getVdsStatic()).when(vdsStaticDao).get(serverId); doReturn(getCluster(true, Version.v4_1)).when(clusterDao).get(any(Guid.class)); } private GlusterVolumeEntity getVolume(int brickCount, boolean withDuplicateBricks){ return getVolume(brickCount, withDuplicateBricks, GlusterVolumeType.DISTRIBUTE, 0, false); } private GlusterVolumeEntity getVolume(int brickCount, boolean withDuplicateBricks, GlusterVolumeType volumeType, int replicaCount, boolean isArbiter) { GlusterVolumeEntity volumeEntity = new GlusterVolumeEntity(); volumeEntity.setId(Guid.newGuid()); volumeEntity.setClusterId(clusterId); volumeEntity.setName("vol1"); volumeEntity.setVolumeType(volumeType); volumeEntity.setBricks(getBricks(volumeEntity.getId(), brickCount, withDuplicateBricks)); volumeEntity.setReplicaCount(replicaCount); volumeEntity.setIsArbiter(isArbiter); return volumeEntity; } private List<GlusterBrickEntity> getBricks(Guid volumeId, int max, boolean withDuplicates) { List<GlusterBrickEntity> bricks = new ArrayList<>(); GlusterBrickEntity brick = null; for (Integer i = 0; i < max; i++) { brick = new GlusterBrickEntity(); brick.setVolumeId(volumeId); brick.setServerId(serverId); brick.setServerName(serverName); brick.setBrickDirectory("/tmp/s" + i.toString()); brick.setStatus(GlusterStatus.UP); bricks.add(brick); } if (max > 0 && withDuplicates) { bricks.add(brick); } return bricks; } @Test public void validateSucceeds() { assertTrue(cmd.validate()); } @Test public void validateSucceedsWithArbiter() { setVolume(getVolume(3, false, GlusterVolumeType.REPLICATE, 3, true)); assertTrue(cmd.validate()); } @Test public void validateFailsWithArbiterAndInvalidReplica() { setVolume(getVolume(2, false, GlusterVolumeType.REPLICATE, 2, true)); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_GLUSTER_ARBITER_VOLUME_SHOULD_BE_REPLICA_3_VOLUME); } @Test public void validateFailsWithArbiterWithClusterDoesNotArbiterVolume() { setVolume(getVolume(3, false, GlusterVolumeType.REPLICATE, 3, true)); doReturn(getCluster(true, Version.v4_0)).when(clusterDao).get(any(Guid.class)); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_GLUSTER_ARBITER_VOLUME_NOT_SUPPORTED); } @Test public void validateFailsWithClusterDoesNotSupportGluster() { doReturn(getCluster(false, Version.v4_1)).when(clusterDao).get(any(Guid.class)); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_CLUSTER_DOES_NOT_SUPPORT_GLUSTER); } @Test public void validateFailsWithDuplicateVolumeName() { doReturn(getVolume(2, false)).when(volumeDao).getByName(clusterId, "vol1"); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_GLUSTER_VOLUME_NAME_ALREADY_EXISTS); } @Test public void validateFailsWithEmptyBricks() { setVolume(getVolume(0, false)); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_BRICKS_REQUIRED); } @Test public void validateFailsWithDuplicateBricks() { setVolume(getVolume(2, true)); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_DUPLICATE_BRICKS); } }