package org.ovirt.engine.ui.uicommonweb.action; import static org.mockito.ArgumentMatchers.anyListOf; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner.Silent; import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.ui.uicommonweb.action.UiAction.ActionFlowState; import org.ovirt.engine.ui.uicompat.FrontendMultipleActionAsyncResult; import org.ovirt.engine.ui.uicompat.IFrontendMultipleActionAsyncCallback; @RunWith(Silent.class) public class UiVdcMultipleActionTest extends AsyncUiActionTest<IFrontendMultipleActionAsyncCallback> { @Test public void runNextWithFirstActionFailureNoWaitForResultTest() { runNextActionFlowWithFirstActionFailureTestCommon(false); } @Test public void runNextWithFirstActionFailureWaitForResultTest() { runNextActionFlowWithFirstActionFailureTestCommon(true); } private void runNextActionFlowWithFirstActionFailureTestCommon(boolean waitFoResult) { UiAction action1 = createAction(waitFoResult, true); UiAction action2 = createAction(waitFoResult, true); action1.then(action2); action1.runAction(); verifyRunActionAndExecuteCallbacksRandomly(action1.getActionFlowState(), waitFoResult); verifyRunActionAndExecuteCallbacksRandomly(true, action1.getActionFlowState(), 2, 1, waitFoResult); assertFinishedWithErrors(Arrays.asList(action1, action2), 1); } @Test public void runMixedActionFlowWithFailureOnDependentAction() { // action1.and(action2).next(action3).and(action4) // action1 and action 2 has failure -> action3 and action4 won't be executed List<UiAction> actions = runActionFlow(ActionType.parallel, ActionType.next, ActionType.parallel); ActionFlowState flowState = actions.get(0).getActionFlowState(); verifyRunActionAndExecuteCallbacksRandomly(false, flowState, 2); verifyRunActionAndExecuteCallbacksRandomly(true, flowState, 4, 2); assertFinishedWithErrors(actions.subList(0, 2), 2); } @Test public void dontRunNextInCaseOfErrorNoWaitForResultTest() { dontRunNextInCaseOfErrorCommon(false); } @Test public void dontRunNextInCaseOfErrorWaitForResultTest() { dontRunNextInCaseOfErrorCommon(true); } private void dontRunNextInCaseOfErrorCommon(boolean waitForResult) { UiAction action1 = createAction(waitForResult, false); UiAction action2 = createAction(); action1.then(action2); action1.runAction(); ActionFlowState flowState = action1.getActionFlowState(); verifyRunActionAndExecuteCallbacksRandomly(flowState, waitForResult); verifyRunAction(1, waitForResult); assertFinishedWithErrors(Collections.singletonList(action1), 1); } @Test public void noParametersTest() { UiAction action = createAction(true); action.runAction(); verifyRunAction(0); assertFinishedWithNoErrors(Collections.singletonList(action)); } @Override protected UiVdcMultipleAction createAction() { return createAction(false); } private UiVdcMultipleAction createAction(boolean emptyParams) { return new UiVdcMultipleAction(ACTION_TYPE, emptyParams ? new ArrayList<VdcActionParametersBase>() : Collections.singletonList(new VdcActionParametersBase()), model); } private UiVdcMultipleAction createAction(boolean waitForResult, boolean runNextInCaseOfError) { return new UiVdcMultipleAction(ACTION_TYPE, Collections.singletonList(new VdcActionParametersBase()), model, waitForResult, runNextInCaseOfError); } @Override protected void verifyRunActionAndExecuteCallbacksRandomly(boolean success, ActionFlowState flowState, int exepectedNumOfRunActionExecutions, int numOfCallbacksFromTheEndToExecute) { verifyRunActionAndExecuteCallbacksRandomly(success, flowState, exepectedNumOfRunActionExecutions, numOfCallbacksFromTheEndToExecute, false); } private void verifyRunActionAndExecuteCallbacksRandomly(boolean success, ActionFlowState flowState, int exepectedNumOfRunActionExecutions, int numOfCallbacksFromTheEndToExecute, boolean waitForResult) { List<IFrontendMultipleActionAsyncCallback> callbacks = verifyRunAction(exepectedNumOfRunActionExecutions, waitForResult); executeCallbacks(success, flowState, callbacks.subList(callbacks.size() - numOfCallbacksFromTheEndToExecute, callbacks.size()), waitForResult); } private void verifyRunActionAndExecuteCallbacksRandomly(ActionFlowState flowState, boolean waitForResult) { verifyRunActionAndExecuteCallbacksRandomly(false, flowState, 1, 1, waitForResult); } private void executeCallbacks(boolean success, ActionFlowState flowState, List<IFrontendMultipleActionAsyncCallback> callbacks, boolean waitForResult) { Collections.shuffle(callbacks); for (IFrontendMultipleActionAsyncCallback callback : callbacks) { assertNotAllDone(flowState); VdcReturnValueBase result = new VdcReturnValueBase(); result.setValid(waitForResult || success); result.setSucceeded(waitForResult && success); callback.executed(new FrontendMultipleActionAsyncResult(ACTION_TYPE, null, Collections.singletonList(result))); } } @Override protected void executeCallbacks(boolean success, ActionFlowState flowState, List<IFrontendMultipleActionAsyncCallback> callbacks) { executeCallbacks(success, flowState, callbacks, false); } private List<IFrontendMultipleActionAsyncCallback> verifyRunAction(int exepectedNumOfRunActionExecutions, boolean waitForResult) { verify(frontend, times(exepectedNumOfRunActionExecutions)).runMultipleAction(eq(ACTION_TYPE), anyListOf(VdcActionParametersBase.class), callbackCaptor.capture(), eq(false), eq(waitForResult)); return callbackCaptor.getAllValues(); } @Override protected List<IFrontendMultipleActionAsyncCallback> verifyRunAction(int exepectedNumOfRunActionExecutions) { return verifyRunAction(exepectedNumOfRunActionExecutions, false); } }