package org.ovirt.engine.core.bll.gluster; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import java.util.ArrayList; import java.util.List; import org.junit.Before; 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.common.action.gluster.GlusterVolumeBricksActionParameters; 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.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.businessentities.network.Network; import org.ovirt.engine.core.common.businessentities.network.NetworkCluster; import org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface; import org.ovirt.engine.core.compat.Guid; 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; public class AddBricksToGlusterVolumeCommandTest extends BaseCommandTest { @Mock GlusterVolumeDao volumeDao; @Mock VdsStaticDao vdsStaticDao; @Mock GlusterBrickDao brickDao; @Mock ClusterDao clusterDao; @Mock NetworkDao networkDao; @Mock InterfaceDao interfaceDao; private static final String serverName = "myhost"; private final Guid clusterId = new Guid("c0dd8ca3-95dd-44ad-a88a-440a6e3d8106"); private final Guid serverId = new Guid("d7f10a21-bbf2-4ffd-aab6-4da0b3b2ccec"); private final Guid volumeId1 = new Guid("8bc6f108-c0ef-43ab-ba20-ec41107220f5"); private final Guid volumeId2 = new Guid("b2cb2f73-fab3-4a42-93f0-d5e4c069a43e"); private final Guid volumeIdRepl = new Guid("b2cb2f73-fab3-4a42-93f0-d3e4c069a52e"); private static final String BRICK_DIRECTORY = "/tmp/s1"; private static final String GLUSTER_NW = "gluster-net"; private static final String SERVER_ADDRESS = "10.70.8.8"; /** * The command under test. */ @Spy @InjectMocks private AddBricksToGlusterVolumeCommand cmd = new AddBricksToGlusterVolumeCommand(new GlusterVolumeBricksActionParameters(), null); private void initTestCommand(Guid volumeId, List<GlusterBrickEntity> bricks, int replicaCount, int stripeCount, boolean force) { cmd.setGlusterVolumeId(volumeId); cmd.getParameters().setBricks(bricks); cmd.getParameters().setReplicaCount(replicaCount); cmd.getParameters().setStripeCount(stripeCount); cmd.getParameters().setForce(force); } private List<GlusterBrickEntity> getBricks(Guid volumeId, int max) { return getBricks(volumeId, max, false); } private List<GlusterBrickEntity> getBricks(Guid volumeId, int max, boolean withDuplicates) { List<GlusterBrickEntity> bricks = new ArrayList<>(); for (Integer i = 0; i < max; i++) { bricks.add(getBrick(volumeId, serverId, "/tmp/s" + i.toString())); } if (max > 0 && withDuplicates) { bricks.add(getBrick(volumeId, serverId, "/tmp/s0")); } return bricks; } private GlusterBrickEntity getBrick(Guid volumeId, Guid serverid, String brickDir) { GlusterBrickEntity brick = new GlusterBrickEntity(); brick.setVolumeId(volumeId); brick.setServerId(serverid); brick.setServerName(serverName); brick.setBrickDirectory(brickDir); brick.setStatus(GlusterStatus.UP); return brick; } private VDS getVds(VDSStatus status) { VDS vds = new VDS(); vds.setId(Guid.newGuid()); vds.setVdsName("gfs1"); vds.setClusterId(clusterId); vds.setStatus(status); return vds; } @Before public void prepareMocks() { doReturn(getVds(VDSStatus.Up)).when(cmd).getUpServer(); doReturn(getSingleBrickVolume(volumeId1)).when(volumeDao).getById(volumeId1); doReturn(getMultiBrickVolume(volumeId2, 2)).when(volumeDao).getById(volumeId2); doReturn(getBrick(volumeId1, serverId, BRICK_DIRECTORY)).when(brickDao).getBrickByServerIdAndDirectory(serverId, BRICK_DIRECTORY); doReturn(getVdsStatic()).when(vdsStaticDao).get(serverId); doReturn(getCluster()).when(cmd).getCluster(); } private void prepareInterfaceMocks() { doReturn(getNetworks()).when(networkDao).getAllForCluster(any(Guid.class)); doReturn(getNetworkInterfaces()).when(interfaceDao).getAllInterfacesForVds(serverId); } private List<Network> getNetworks() { List<Network> networks = new ArrayList<>(); Network nw = new Network(); nw.setName(GLUSTER_NW); NetworkCluster nc = new NetworkCluster(); nc.setGluster(true); nw.setCluster(nc); networks.add(nw); return networks; } private List<VdsNetworkInterface> getNetworkInterfaces() { List<VdsNetworkInterface> ifaces = new ArrayList<>(); VdsNetworkInterface iface = new VdsNetworkInterface(); iface.setNetworkName(GLUSTER_NW); iface.setId(Guid.newGuid()); iface.setIpv4Address(SERVER_ADDRESS); ifaces.add(iface); return ifaces; } private Cluster getCluster() { Cluster cluster = new Cluster(); cluster.setId(clusterId); cluster.setVirtService(true); cluster.setGlusterService(true); return cluster; } private VdsStatic getVdsStatic() { VdsStatic vds = new VdsStatic(); vds.setId(serverId); vds.setClusterId(clusterId); vds.setHostName(serverName); return vds; } private GlusterVolumeEntity getSingleBrickVolume(Guid volumeId) { GlusterVolumeEntity volume = getGlusterVolume(volumeId); volume.setStatus(GlusterStatus.UP); volume.setBricks(getBricks(volumeId, 1)); volume.setClusterId(clusterId); return volume; } private GlusterVolumeEntity getMultiBrickVolume(Guid volumeId, int brickCount) { GlusterVolumeEntity volume = getGlusterVolume(volumeId); volume.setStatus(GlusterStatus.UP); volume.setBricks(getBricks(volumeId, brickCount)); volume.setClusterId(clusterId); return volume; } private GlusterVolumeEntity getGlusterVolume(Guid id) { GlusterVolumeEntity volumeEntity = new GlusterVolumeEntity(); volumeEntity.setId(id); volumeEntity.setName("test-vol"); volumeEntity.addAccessProtocol(AccessProtocol.GLUSTER); volumeEntity.addTransportType(TransportType.TCP); volumeEntity.setVolumeType(GlusterVolumeType.DISTRIBUTE); volumeEntity.setClusterId(clusterId); return volumeEntity; } @Test public void validateSucceeds() { initTestCommand(volumeId2, getBricks(volumeId2, 1), 2, 0, false); assertTrue(cmd.validate()); } @Test public void validateFails() { initTestCommand(volumeId1, getBricks(volumeId1, 2), 0, 4, false); assertFalse(cmd.validate()); } @Test public void validateFailsWithDuplicateBricks() { initTestCommand(volumeId2, getBricks(volumeId2, 1, true), 2, 0, false); assertFalse(cmd.validate()); } @Test public void validateFailsDiffInterface() { initTestCommand(volumeId1, getBricks(volumeId1, 2), 0, 4, false); prepareInterfaceMocks(); assertFalse(cmd.validate()); } @Test public void validateFailsOnSameServer() { initTestCommand(volumeIdRepl, getBricks(volumeIdRepl, 3, true), 3, 0, false); GlusterVolumeEntity vol = getMultiBrickVolume(volumeIdRepl, 3); vol.setVolumeType(GlusterVolumeType.REPLICATE); vol.setReplicaCount(3); doReturn(vol).when(volumeDao).getById(volumeIdRepl); assertFalse(cmd.validate()); } @Test public void validateFailsOnSameServerIncreasingReplica() { initTestCommand(volumeIdRepl, getBricks(volumeIdRepl, 2, true), 3, 0, false); GlusterVolumeEntity vol = getMultiBrickVolume(volumeIdRepl, 4); vol.setVolumeType(GlusterVolumeType.DISTRIBUTED_REPLICATE); vol.setReplicaCount(2); doReturn(vol).when(volumeDao).getById(volumeIdRepl); assertFalse(cmd.validate()); } @Test public void validateSucceedsonServerCheckIncreasingReplica() { List<GlusterBrickEntity> bricks = new ArrayList<>(); bricks.add(getBrick(volumeIdRepl, Guid.newGuid(), "/brick1")); bricks.add(getBrick(volumeIdRepl, Guid.newGuid(), "/brick2")); initTestCommand(volumeIdRepl, bricks, 3, 0, false); doReturn(getVdsStatic()).when(vdsStaticDao).get(any(Guid.class)); GlusterVolumeEntity vol = getMultiBrickVolume(volumeIdRepl, 4); vol.setVolumeType(GlusterVolumeType.DISTRIBUTED_REPLICATE); vol.setReplicaCount(2); doReturn(vol).when(volumeDao).getById(volumeIdRepl); assertTrue(cmd.validate()); } @Test public void validateSucceedsonServerCheck() { List<GlusterBrickEntity> bricks = new ArrayList<>(); bricks.add(getBrick(volumeIdRepl, Guid.newGuid(), "/brick1")); bricks.add(getBrick(volumeIdRepl, Guid.newGuid(), "/brick2")); initTestCommand(volumeIdRepl, bricks, 2, 0, false); doReturn(getVdsStatic()).when(vdsStaticDao).get(any(Guid.class)); GlusterVolumeEntity vol = getMultiBrickVolume(volumeIdRepl, 4); vol.setVolumeType(GlusterVolumeType.DISTRIBUTED_REPLICATE); vol.setReplicaCount(2); doReturn(vol).when(volumeDao).getById(volumeIdRepl); assertTrue(cmd.validate()); } @Test public void validateFailsOnNull() { initTestCommand(null, null, 0, 0, false); assertFalse(cmd.validate()); } }