package org.ovirt.engine.core.bll.pm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.ovirt.engine.core.common.businessentities.FencingPolicy;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.pm.FenceActionType;
import org.ovirt.engine.core.common.businessentities.pm.FenceAgent;
import org.ovirt.engine.core.common.businessentities.pm.FenceOperationResult;
import org.ovirt.engine.core.common.businessentities.pm.FenceOperationResult.Status;
import org.ovirt.engine.core.common.businessentities.pm.PowerStatus;
import org.ovirt.engine.core.compat.Guid;
@RunWith(MockitoJUnitRunner.class)
public class HostFenceActionExecutorTest {
@Mock
VDS fencedHost;
@Mock
SingleAgentFenceActionExecutor agentExecutor1;
@Mock
SingleAgentFenceActionExecutor agentExecutor2;
HostFenceActionExecutor executor;
List<FenceAgent> fenceAgents;
@Before
public void setup() {
executor = spy(new HostFenceActionExecutor(fencedHost, new FencingPolicy()));
doReturn(agentExecutor1).doReturn(agentExecutor2).when(executor).createFenceActionExecutor(anyList());
}
/**
* Test successful fence action when the 1st of 2 sequential fence agents returns success
*/
@Test
public void successfulFenceWith1stSuccess() {
mockFenceAgents();
// result of fence action invoked on 1st sequential agent
mockFenceResult(
agentExecutor1,
new FenceOperationResult(Status.SUCCESS, PowerStatus.ON));
// result of fence action invoked on 2nd sequential agent - set it to error, so we verify that it's not used
mockFenceResult(
agentExecutor2,
new FenceOperationResult(Status.ERROR, PowerStatus.UNKNOWN));
FenceOperationResult result = executor.fence(FenceActionType.STATUS);
assertEquals(Status.SUCCESS, result.getStatus());
assertEquals(PowerStatus.ON, result.getPowerStatus());
}
/**
* Test successful fence action when the 1st of 2 sequential fence agents returns error and 2nd one return success
*/
@Test
public void successfulFenceWith1stError2ndSuccess() {
mockFenceAgents();
// result of fence action invoked on 1st sequential agent
mockFenceResult(
agentExecutor1,
new FenceOperationResult(Status.ERROR, PowerStatus.UNKNOWN));
// result of fence action invoked on 2nd sequential agent
mockFenceResult(
agentExecutor2,
new FenceOperationResult(Status.SUCCESS, PowerStatus.ON));
FenceOperationResult result = executor.fence(FenceActionType.STATUS);
assertEquals(Status.SUCCESS, result.getStatus());
assertEquals(PowerStatus.ON, result.getPowerStatus());
}
/**
* Test failed fence action when both of 2 sequential fence agents return error
*/
@Test
public void failedFenceWithAllError() {
mockFenceAgents();
// result of fence action invoked on 1st sequential agent
mockFenceResult(
agentExecutor1,
new FenceOperationResult(Status.ERROR, PowerStatus.UNKNOWN));
// result of fence action invoked on 2nd sequential agent
mockFenceResult(
agentExecutor2,
new FenceOperationResult(Status.ERROR, PowerStatus.UNKNOWN));
FenceOperationResult result = executor.fence(FenceActionType.STATUS);
assertEquals(Status.ERROR, result.getStatus());
assertEquals(PowerStatus.UNKNOWN, result.getPowerStatus());
}
/**
* Test successful status action using specified fence agent
*/
@Test
public void successfulStatusWithSpecifiedFenceAgent() {
// result of fence action invoked on specified agent
mockFenceResult(
agentExecutor1,
new FenceOperationResult(Status.SUCCESS, PowerStatus.ON));
FenceOperationResult result = executor.getFenceAgentStatus(createFenceAgent(1));
assertEquals(Status.SUCCESS, result.getStatus());
assertEquals(PowerStatus.ON, result.getPowerStatus());
}
/**
* Test failed status action using specified fence agent
*/
@Test
public void failedStatusWithSpecifiedFenceAgent() {
// result of fence action invoked on specified agent
mockFenceResult(
agentExecutor1,
new FenceOperationResult(Status.ERROR, PowerStatus.UNKNOWN));
FenceOperationResult result = executor.getFenceAgentStatus(createFenceAgent(1));
assertEquals(Status.ERROR, result.getStatus());
assertEquals(PowerStatus.UNKNOWN, result.getPowerStatus());
}
/**
* Test that host is powered off when status action returns power off
*/
@Test
public void hostIsPoweredOffWhenFenceStatusReturnsOff() {
mockFenceAgent();
// result of fence action invoked on specified agent
mockFenceResult(
agentExecutor1,
new FenceOperationResult(Status.SUCCESS, PowerStatus.OFF));
assertTrue(executor.isHostPoweredOff());
}
/**
* Test that host is not powered off when status action returns power on
*/
@Test
public void hostIsNotPoweredOffWhenFenceStatusReturnsOn() {
mockFenceAgent();
// result of fence action invoked on specified agent
mockFenceResult(
agentExecutor1,
new FenceOperationResult(Status.SUCCESS, PowerStatus.ON));
assertFalse(executor.isHostPoweredOff());
}
/**
* Test that host is not powered off when status action returns error
*/
@Test
public void hostIsNotPoweredOffWhenFenceStatusFailed() {
mockFenceAgent();
// result of fence action invoked on specified agent
mockFenceResult(
agentExecutor1,
new FenceOperationResult(Status.ERROR, PowerStatus.UNKNOWN));
assertFalse(executor.isHostPoweredOff());
}
/**
* Tests {@code SingleAgentFenceActionExecutor} creation for single fence agent
*/
@Test
public void testSingleAgentFenceActionExecutorUsage() {
HostFenceActionExecutor executor = new HostFenceActionExecutor(fencedHost, new FencingPolicy());
assertTrue(
executor.createFenceActionExecutor(createSingleAgentList(1))
instanceof SingleAgentFenceActionExecutor);
}
/**
* Tests {@code ConcurrentAgentsFenceActionExecutor} creation for concurrent fence agents
*/
@Test
public void testConcurrentAgentsFenceActionExecutorUsage() {
HostFenceActionExecutor executor = new HostFenceActionExecutor(fencedHost, new FencingPolicy());
assertTrue(
executor.createFenceActionExecutor(createConcurrentAgentsList(2, 1))
instanceof ConcurrentAgentsFenceActionExecutor);
}
protected FenceAgent createFenceAgent(int order) {
FenceAgent agent = new FenceAgent();
agent.setId(Guid.newGuid());
agent.setOrder(order);
return agent;
}
protected List<FenceAgent> createSingleAgentList(int order) {
List<FenceAgent> fenceAgents = new ArrayList<>();
fenceAgents.add(createFenceAgent(order));
return fenceAgents;
}
protected List<FenceAgent> createConcurrentAgentsList(int count, int order) {
List<FenceAgent> fenceAgents = new ArrayList<>();
for (int i = 0; i < count; i++) {
fenceAgents.add(createFenceAgent(order));
}
return fenceAgents;
}
protected List<FenceAgent> create2SequentialFenceAgents() {
List<FenceAgent> fenceAgents = createSingleAgentList(1);
fenceAgents.addAll(createSingleAgentList(2));
return fenceAgents;
}
protected void mockFenceResult(FenceActionExecutor executor, FenceOperationResult result) {
doReturn(result).when(executor).fence(any(FenceActionType.class));
}
protected void mockFenceAgents() {
fenceAgents = create2SequentialFenceAgents();
doReturn(fenceAgents).when(fencedHost).getFenceAgents();
}
protected void mockFenceAgent() {
fenceAgents = createSingleAgentList(1);
doReturn(fenceAgents).when(fencedHost).getFenceAgents();
}
}