package org.ovirt.engine.core.bll.hostdeploy;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.ovirt.engine.core.bll.utils.ClusterUtils;
import org.ovirt.engine.core.bll.utils.EngineSSHClient;
import org.ovirt.engine.core.bll.utils.GlusterUtil;
import org.ovirt.engine.core.bll.validator.HostValidator;
import org.ovirt.engine.core.common.action.hostdeploy.AddVdsActionParameters;
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.errors.EngineMessage;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.Version;
import org.ovirt.engine.core.dao.VdsDao;
import org.ovirt.engine.core.dao.gluster.GlusterDBUtils;
import org.ovirt.engine.core.utils.MockConfigRule;
@RunWith(MockitoJUnitRunner.class)
public class AddVdsCommandTest {
private static final String PEER_1 = "peer1";
private static final Guid vdsId = Guid.newGuid();
@Spy
@InjectMocks
private AddVdsCommand<AddVdsActionParameters> command = new AddVdsCommand<>(createParameters(), null);
@Mock
private VdsDao vdsDaoMock;
@Mock
private ClusterUtils clusterUtils;
@Mock
private GlusterUtil glusterUtil;
@Mock
private GlusterDBUtils glusterDBUtils;
@Mock
private EngineSSHClient sshClient;
@Mock
private HostValidator validator;
@ClassRule
public static MockConfigRule configRule = new MockConfigRule();
private VDS makeTestVds(Guid vdsId) {
VDS newVdsData = new VDS();
newVdsData.setHostName("BUZZ");
newVdsData.setSshPort(22);
newVdsData.setSshUsername("root");
newVdsData.setSshKeyFingerprint("1234");
newVdsData.setVdsName("BAR");
newVdsData.setClusterCompatibilityVersion(new Version("1.2.3"));
newVdsData.setClusterId(Guid.newGuid());
newVdsData.setId(vdsId);
return newVdsData;
}
public AddVdsActionParameters createParameters() {
AddVdsActionParameters parameters = new AddVdsActionParameters();
parameters.setPassword("secret");
VDS newVds = makeTestVds(vdsId);
parameters.setvds(newVds);
return parameters;
}
private void setupCommonMock(boolean glusterEnabled) throws Exception {
mockHostValidator();
doReturn(glusterEnabled).when(command).isGlusterSupportEnabled();
doReturn(clusterUtils).when(command).getClusterUtils();
doReturn(true).when(command).validateCluster();
doReturn(sshClient).when(command).getSSHClient();
Version version = new Version("1.2.3");
Cluster cluster = new Cluster();
cluster.setCompatibilityVersion(version);
doReturn(cluster).when(command).getCluster();
}
private void mockHostValidator() {
doReturn(validator).when(command).getHostValidator();
}
private void setupVirtMock() throws Exception {
setupCommonMock(false);
}
private void setupGlusterMock(boolean clusterHasServers, VDS upServer, boolean hasPeers) throws Exception {
setupCommonMock(true);
when(glusterUtil.getPeers(any(EngineSSHClient.class))).thenReturn(hasPeers ? Collections.singleton(PEER_1)
: Collections.emptySet());
when(clusterUtils.hasServers(any(Guid.class))).thenReturn(clusterHasServers);
when(vdsDaoMock.getAllForCluster(any(Guid.class))).thenReturn(mockVdsInDb(clusterHasServers ? VDSStatus.Maintenance
: VDSStatus.Initializing));
when(glusterUtil.getUpServer(any(Guid.class))).thenReturn(upServer);
}
private List<VDS> mockVdsInDb(VDSStatus status) {
List<VDS> vdsList = new ArrayList<>();
VDS vds = new VDS();
vds.setStatus(status);
vdsList.add(vds);
return vdsList;
}
@Test
public void validateVirtOnlySucceeds() throws Exception {
setupVirtMock();
assertTrue(command.validate());
}
@Test
public void validateSucceedsOnEmptyClusterEvenWhenGlusterServerHasPeers() throws Exception {
setupGlusterMock(false, null, true);
assertTrue(command.validate());
}
@Test
public void validateSucceedsWhenHasPeersThrowsException() throws Exception {
setupGlusterMock(true, new VDS(), true);
when(glusterUtil.getPeers(any(EngineSSHClient.class))).thenThrow(new RuntimeException());
assertTrue(command.validate());
}
@Test
public void validateFailsWhenGlusterServerHasPeers() throws Exception {
setupGlusterMock(true, new VDS(), true);
when(glusterDBUtils.serverExists(any(Guid.class), eq(PEER_1))).thenReturn(false);
assertFalse(command.validate());
assertTrue(command.getReturnValue()
.getValidationMessages()
.contains(EngineMessage.SERVER_ALREADY_PART_OF_ANOTHER_CLUSTER.toString()));
}
@Test
public void validateSucceedsWhenGlusterServerHasPeersThatExistInDB() throws Exception {
setupGlusterMock(true, new VDS(), true);
when(glusterDBUtils.serverExists(any(Guid.class), eq(PEER_1))).thenReturn(true);
assertTrue(command.validate());
}
@Test
public void validateSucceedsWhenGlusterServerHasNoPeers() throws Exception {
setupGlusterMock(true, new VDS(), false);
assertTrue(command.validate());
}
@Test
public void validateSuccessForGlusterServerWhenUpServerExists() throws Exception {
setupGlusterMock(true, new VDS(), false);
assertTrue(command.validate());
}
@Test
public void validateFailsForGlusterServerWhenNoUpServer() throws Exception {
setupGlusterMock(true, null, false);
assertFalse(command.validate());
assertTrue(command.getReturnValue()
.getValidationMessages()
.contains(EngineMessage.ACTION_TYPE_FAILED_NO_GLUSTER_HOST_TO_PEER_PROBE.toString()));
}
@Test
public void provisioningValidated() throws Exception {
setupVirtMock();
assertTrue(command.validate());
verify(validator, times(1)).provisioningComputeResourceValid(anyBoolean(), any());
verify(validator, times(1)).provisioningHostGroupValid(anyBoolean(), any());
}
}