package org.ovirt.engine.core.bll;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.powermock.api.mockito.PowerMockito.doThrow;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.action.AttachNetworkToVdsGroupParameter;
import org.ovirt.engine.core.common.businessentities.VDSGroup;
import org.ovirt.engine.core.common.businessentities.network;
import org.ovirt.engine.core.common.businessentities.network_cluster;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.VdcBllMessages;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;
import org.ovirt.engine.core.dao.NetworkClusterDAO;
import org.ovirt.engine.core.dao.NetworkDAO;
import org.ovirt.engine.core.dao.VdsGroupDAO;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.dao.DataIntegrityViolationException;
@PrepareForTest({DbFacade.class})
@RunWith(PowerMockRunner.class)
public class AttachNetworkToVdsGroupCommandTest {
private VDSGroup existingGroup = new VDSGroup();
private network network = createNetwork();
private DbFacade dbFacade = mock(DbFacade.class);
private AttachNetworkToVdsGroupCommand<AttachNetworkToVdsGroupParameter> command;
public AttachNetworkToVdsGroupCommandTest() {
mockStatic(DbFacade.class);
}
@Before
public void setup() {
createCommand();
when(DbFacade.getInstance()).thenReturn(getDbFacadeMock());
}
@Test
public void networkExists() {
simulateNetworkAlreadyExists();
simulateVdsGroupExists();
assertCanDoActionFailure(VdcBllMessages.NETWORK_NETWORK_ALREADY_ATTACH_TO_CLUSTER.toString());
}
@Test
public void newNetwork() {
simulateNetworkDoesNotExist();
simulateVdsGroupExists();
assertCanDoActionSucceeds();
}
@Test
public void noVdsGroup() {
simulateNetworkDoesNotExist();
simulateVdsGroupDoesNotExist();
assertCanDoActionFailure(VdcBllMessages.VDS_CLUSTER_IS_NOT_VALID.toString());
}
@Test
public void raceConditionVdsGroupRemoved() {
simulateVdsGroupExists();
simulateVdsGroupWasRemoved();
assertExecuteActionFailure();
}
private network createNetwork() {
network = new network();
network.setname("test network");
return network;
}
public void createCommand() {
AttachNetworkToVdsGroupParameter param = new AttachNetworkToVdsGroupParameter(getExistingVdsGroupId(), getNetwork());
command = new AttachNetworkToVdsGroupCommand(param);
}
private void simulateNetworkAlreadyExists() {
dbFacadeReturnNetworkListFromDb();
}
private void simulateNetworkDoesNotExist() {
dbFacadeReturnEmptyNetworkList();
}
private void simulateVdsGroupExists() {
dbFacadeReturnVdsGroup();
}
private void simulateVdsGroupDoesNotExist() {
dbFacadeReturnNoVdsGroup();
}
private void simulateVdsGroupWasRemoved() {
dbFacadeThrowOnNetworkClusterSave();
}
private void dbFacadeReturnNoVdsGroup() {
VdsGroupDAO dao = mock(VdsGroupDAO.class);
when(getDbFacadeMock().getVdsGroupDAO()).thenReturn(dao);
when(dao.get(any(Guid.class))).thenReturn(null);
}
private void dbFacadeReturnNetworkListFromDb() {
NetworkDAO dao = mock(NetworkDAO.class);
when(getDbFacadeMock().getNetworkDAO()).thenReturn(dao);
when(dao.getAllForCluster(any(Guid.class))).thenReturn(getNetworkList());
}
private void dbFacadeReturnEmptyNetworkList() {
NetworkDAO dao = mock(NetworkDAO.class);
when(getDbFacadeMock().getNetworkDAO()).thenReturn(dao);
when(dao.getAllForCluster(any(Guid.class))).thenReturn(new ArrayList<network>());
}
private void dbFacadeReturnVdsGroup() {
VdsGroupDAO dao = mock(VdsGroupDAO.class);
when(getDbFacadeMock().getVdsGroupDAO()).thenReturn(dao);
when(dao.get(any(Guid.class))).thenReturn(existingGroup);
}
private void dbFacadeThrowOnNetworkClusterSave() {
NetworkClusterDAO dao = mock(NetworkClusterDAO.class);
when(getDbFacadeMock().getNetworkClusterDAO()).thenReturn(dao);
doThrow(new DataIntegrityViolationException("test violations")).when(dao).save(Matchers.<network_cluster>any(network_cluster.class));
}
private DbFacade getDbFacadeMock() {
return dbFacade;
}
private network getNetwork() {
return network;
}
private VDSGroup getExistingVdsGroupId() {
return existingGroup;
}
private List<network> getNetworkList() {
ArrayList<network> list = new ArrayList<network>();
list.add(network);
return list;
}
private void assertCanDoActionFailure(final String messageToVerify) {
assertFalse(command.canDoAction());
assertTrue(command.getReturnValue().getCanDoActionMessages().contains(messageToVerify));
}
private void assertCanDoActionSucceeds() {
assertTrue(command.canDoAction());
}
private void assertExecuteActionFailure() {
try {
command.executeCommand();
} catch (Exception e) {
}
assertFalse(command.getReturnValue().getSucceeded());
assertEquals(AuditLogType.NETWORK_ATTACH_NETWORK_TO_VDS_GROUP_FAILED, command.getAuditLogTypeValue());
}
}