package org.ovirt.engine.ui.frontend.communication;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.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.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.ovirt.engine.core.common.action.VdcActionParametersBase;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.shared.EventBus;
@SuppressWarnings({ "unchecked", "rawtypes" })
@RunWith(MockitoJUnitRunner.class)
public class OperationProcessorTest {
OperationProcessor testProcessor;
@Mock
EventBus gwtEventBus;
@Mock
CommunicationProvider mockProvider;
@Mock
VdcOperationManager mockOperationManager;
@Mock
VdcOperationCallback<VdcOperation<?, ?>, Object> mockCallback1;
@Mock
VdcOperationCallback<VdcOperation<?, ?>, Object> mockCallback2;
@Mock
VdcOperationCallback<VdcOperation<?, ?>, Object> mockCallback3;
@Mock
VdcOperationCallbackList<VdcOperation<?, ?>, List<VdcReturnValueBase>> mockCallbackList1;
@Mock
VdcOperationCallbackList<VdcOperation<?, ?>, List<VdcReturnValueBase>> mockCallbackList2;
@Mock
VdcOperationCallbackList<VdcOperation<?, ?>, List<VdcReturnValueBase>> mockCallbackList3;
@Mock
Scheduler mockScheduler;
@Captor
ArgumentCaptor<List<VdcOperation<?, ?>>> operationListCaptor;
@Before
public void setUp() throws Exception {
testProcessor = new OperationProcessor(mockProvider);
testProcessor.setScheduler(mockScheduler);
}
@Test
public void testOnOperationAvailableSingle() {
VdcActionParametersBase testParameter = new VdcActionParametersBase();
VdcOperation<VdcActionType, VdcActionParametersBase> testOperation =
new VdcOperation<>(VdcActionType.AddEventSubscription, testParameter, mockCallback1);
when(mockOperationManager.pollOperation()).thenReturn((VdcOperation) testOperation).thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
// Test that we inserted the callback from the processor.
assertFalse("The callbacks should not match.", //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().equals(mockCallback1));
}
@Test
public void testOnOperationAvailableList() {
VdcActionParametersBase testActionParameter = new VdcActionParametersBase();
VdcQueryParametersBase testQueryParameter = new VdcQueryParametersBase();
VdcOperation testOperation1 = new VdcOperation(VdcActionType.AddEventSubscription, testActionParameter,
mockCallback1);
VdcOperation testOperation2 = new VdcOperation(VdcQueryType.Search, testQueryParameter, mockCallback2);
VdcOperation testOperation3 = new VdcOperation(VdcActionType.AddEmptyStoragePool, testActionParameter,
mockCallback3);
when(mockOperationManager.pollOperation()).thenReturn(testOperation1).thenReturn(testOperation2)
.thenReturn(testOperation3).thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
assertEquals("Should have 3 operations", 3, operationListCaptor.getValue().size()); //$NON-NLS-1$
// Test that we inserted the callback from the processor.
assertFalse("The callbacks should not match.", //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().equals(mockCallback1));
assertFalse("The callbacks should not match.", //$NON-NLS-1$
operationListCaptor.getValue().get(1).getCallback().equals(mockCallback2));
assertFalse("The callbacks should not match.", //$NON-NLS-1$
operationListCaptor.getValue().get(2).getCallback().equals(mockCallback3));
}
@Test
public void testOnOperationAvailableSingle_success() {
VdcActionParametersBase testParameter = new VdcActionParametersBase();
VdcOperation<VdcActionType, VdcActionParametersBase> testOperation =
new VdcOperation<>(VdcActionType.AddEventSubscription, testParameter, mockCallback1);
when(mockOperationManager.pollOperation()).thenReturn((VdcOperation) testOperation).thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
Object testResult = new Object();
operationListCaptor.getValue().get(0).getCallback().onSuccess(testOperation, testResult);
// Verify that the original callback is called.
verify(mockCallback1).onSuccess(testOperation, testResult);
}
@Test
public void testOnOperationAvailableSingle_failure_action_noretry() {
VdcActionParametersBase testParameter = new VdcActionParametersBase();
VdcOperation<VdcActionType, VdcActionParametersBase> testOperation =
new VdcOperation<>(VdcActionType.AddEventSubscription, testParameter, mockCallback1);
when(mockOperationManager.pollOperation()).thenReturn((VdcOperation) testOperation).thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
Exception testException = new Exception("This is an exception"); //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().onFailure(testOperation, testException);
// Verify that the original callback is called.
verify(mockCallback1).onFailure(testOperation, testException);
}
@Test
public void testOnOperationAvailableSingle_failure_with_retry() {
VdcQueryParametersBase testParameter = new VdcQueryParametersBase();
VdcOperation<VdcQueryType, VdcQueryParametersBase>testOperation =
new VdcOperation<>(VdcQueryType.Search, testParameter, mockCallback1);
when(mockOperationManager.pollOperation()).thenReturn((VdcOperation) testOperation).thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
Exception testException = new Exception("This is an exception"); //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().onFailure(operationListCaptor.getValue().get(0),
testException);
// Verify that the original callback is never called.
verify(mockCallback1, never()).onFailure(operationListCaptor.getValue().get(0), testException);
// Verify that the operation is put back in the queue.
verify(mockOperationManager).addOperation(operationListCaptor.getValue().get(0));
// Verify that the callback on the operation is no longer the original.
assertFalse("callbacks should not match", //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().equals(mockCallback1));
}
@Test
public void testOnOperationAvailableSingle_failure_query_noretry() {
VdcQueryParametersBase testParameter = new VdcQueryParametersBase();
// Setup 'previous' retries, so we have exhausted the retries.
VdcOperation<VdcQueryType, VdcQueryParametersBase> testOperation = new VdcOperation<>(VdcQueryType.Search, testParameter, mockCallback1);
testOperation = new VdcOperation(testOperation, mockCallback2);
testOperation = new VdcOperation(testOperation, mockCallback2);
testOperation = new VdcOperation(testOperation, mockCallback2);
testOperation = new VdcOperation(testOperation, mockCallback2);
when(mockOperationManager.pollOperation()).thenReturn((VdcOperation) testOperation).thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
Exception testException = new Exception("This is an exception"); //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().onFailure(testOperation, testException);
// Verify that the original callback is called.
verify(mockCallback1).onFailure(testOperation, testException);
}
@Test
public void testOnOperationAvailableMultiple_success() {
VdcActionParametersBase testParameter = new VdcActionParametersBase();
VdcOperation testOperation1 = new VdcOperation(VdcActionType.AddEventSubscription, testParameter,
mockCallback1);
VdcOperation testOperation2 = new VdcOperation(VdcActionType.AddEventSubscription, testParameter,
mockCallback2);
when(mockOperationManager.pollOperation()).thenReturn(testOperation1).thenReturn(testOperation2).
thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
assertFalse("The callbacks should not match", operationListCaptor.getValue().get(0) //$NON-NLS-1$
.getCallback().equals(mockCallback1));
assertFalse("The callbacks should not match", operationListCaptor.getValue().get(1) //$NON-NLS-1$
.getCallback().equals(mockCallback2));
List<VdcReturnValueBase> resultList1 = new ArrayList<>();
List<VdcReturnValueBase> resultList2 = new ArrayList<>();
VdcReturnValueBase result1 = new VdcReturnValueBase();
VdcReturnValueBase result2 = new VdcReturnValueBase();
resultList1.add(result1);
resultList2.add(result2);
operationListCaptor.getValue().get(0).getCallback().onSuccess(operationListCaptor.getValue().get(0),
resultList1);
verify(mockCallback1).onSuccess(testOperation1, resultList1);
operationListCaptor.getValue().get(1).getCallback().onSuccess(operationListCaptor.getValue().get(1),
resultList2);
verify(mockCallback2).onSuccess(testOperation2, resultList2);
}
@Test
public void testOnOperationAvailableMultiple_success_samecallback() {
VdcActionParametersBase testParameter = new VdcActionParametersBase();
VdcOperation testOperation1 = new VdcOperation(VdcActionType.AddEventSubscription, testParameter,
mockCallback1);
VdcOperation testOperation2 = new VdcOperation(VdcActionType.AddEventSubscription, testParameter,
mockCallback1);
when(mockOperationManager.pollOperation()).thenReturn(testOperation1).thenReturn(testOperation2).
thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
assertFalse("The callbacks should not match", operationListCaptor.getValue() //$NON-NLS-1$
.get(0).getCallback().equals(mockCallback1));
assertFalse("The callbacks should not match", operationListCaptor.getValue() //$NON-NLS-1$
.get(1).getCallback().equals(mockCallback2));
VdcReturnValueBase result1 = new VdcReturnValueBase();
operationListCaptor.getValue().get(0).getCallback().onSuccess(operationListCaptor.getValue().get(0), result1);
verify(mockCallback1).onSuccess(testOperation1, result1);
verify(mockCallback2, never()).onSuccess(eq(testOperation2), any());
}
@Test
public void testOnOperationAvailableMultiple_success_with_retry() {
VdcActionParametersBase testParameter = new VdcActionParametersBase();
VdcOperation testOperation1 = new VdcOperation(VdcActionType.AddEventSubscription, testParameter,
mockCallback1);
// This is the 'retry'.
testOperation1 = new VdcOperation(testOperation1, mockCallback3);
VdcOperation testOperation2 = new VdcOperation(VdcActionType.AddEventSubscription, testParameter,
mockCallback2);
when(mockOperationManager.pollOperation()).thenReturn(testOperation1).thenReturn(testOperation2).
thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
assertFalse("The callbacks should not match", operationListCaptor.getValue() //$NON-NLS-1$
.get(0).getCallback().equals(mockCallback1));
assertFalse("The callbacks should not match", operationListCaptor.getValue() //$NON-NLS-1$
.get(1).getCallback().equals(mockCallback2));
List<VdcReturnValueBase> resultList = new ArrayList<>();
VdcReturnValueBase result1 = new VdcReturnValueBase();
VdcReturnValueBase result2 = new VdcReturnValueBase();
resultList.add(result1);
resultList.add(result2);
operationListCaptor.getValue().get(0).getCallback().onSuccess(operationListCaptor.getValue().get(0), result1);
operationListCaptor.getValue().get(1).getCallback().onSuccess(operationListCaptor.getValue().get(1), result2);
verify(mockCallback1).onSuccess(testOperation1, resultList.get(0));
verify(mockCallback2).onSuccess(testOperation2, resultList.get(1));
verify(mockCallback3, never()).onSuccess((VdcOperation) any(), any());
}
@Test
public void testOnOperationAvailableMultipleAction_failure() {
VdcActionParametersBase testParameter = new VdcActionParametersBase();
VdcOperation testOperation1 = new VdcOperation(VdcActionType.AddEventSubscription, testParameter,
mockCallback1);
VdcOperation testOperation2 = new VdcOperation(VdcActionType.AddEventSubscription, testParameter,
mockCallback2);
when(mockOperationManager.pollOperation()).thenReturn(testOperation1).thenReturn(testOperation2).
thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
assertFalse("The callbacks should not match", operationListCaptor.getValue() //$NON-NLS-1$
.get(0).getCallback().equals(mockCallback1));
assertFalse("The callbacks should not match", operationListCaptor.getValue() //$NON-NLS-1$
.get(1).getCallback().equals(mockCallback2));
Exception testException = new Exception("this is an exception"); //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().onFailure(operationListCaptor.getValue().get(0),
testException);
verify(mockCallback1).onFailure(testOperation1, testException);
operationListCaptor.getValue().get(0).getCallback().onFailure(operationListCaptor.getValue().get(1),
testException);
verify(mockCallback2).onFailure(testOperation2, testException);
}
@Test
public void testOnOperationAvailableMultipleQuery_failure() {
VdcQueryParametersBase testParameter = new VdcQueryParametersBase();
VdcOperation testOperation1 = new VdcOperation(VdcQueryType.GetDirectoryGroupById, testParameter,
mockCallback1);
VdcOperation testOperation2 = new VdcOperation(VdcQueryType.Search, testParameter,
mockCallback2);
when(mockOperationManager.pollOperation()).thenReturn(testOperation1).thenReturn(testOperation2).
thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
assertFalse("The callbacks should not match", operationListCaptor.getValue() //$NON-NLS-1$
.get(0).getCallback().equals(mockCallback1));
assertFalse("The callbacks should not match", operationListCaptor.getValue() //$NON-NLS-1$
.get(1).getCallback().equals(mockCallback2));
Exception testException = new Exception("this is an exception"); //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().onFailure(operationListCaptor.getValue().get(0),
testException);
operationListCaptor.getValue().get(1).getCallback().onFailure(operationListCaptor.getValue().get(1),
testException);
verify(mockCallback1, never()).onFailure(testOperation1, testException);
verify(mockCallback2, never()).onFailure(testOperation2, testException);
verify(mockOperationManager).addOperation(testOperation1);
}
@Test
public void testOnOperationAvailableMultiple_same_success() {
VdcQueryParametersBase testParameter = new VdcQueryParametersBase();
List<VdcOperation<?, ?>> testOperation1List = new ArrayList<>();
VdcOperation<VdcQueryType, VdcQueryParametersBase> testOperation1 =
new VdcOperation<>(VdcQueryType.Search, testParameter, mockCallbackList1);
testOperation1List.add(testOperation1);
VdcOperation<VdcQueryType, VdcQueryParametersBase> testOperation2 =
new VdcOperation<>(VdcQueryType.GetDirectoryGroupById, testParameter, mockCallbackList2);
when(mockOperationManager.pollOperation()).thenReturn((VdcOperation) testOperation1).
thenReturn((VdcOperation) testOperation1).thenReturn((VdcOperation) testOperation2).thenReturn(null);
testProcessor.processAvailableOperations(mockOperationManager);
verify(mockProvider).transmitOperationList(operationListCaptor.capture());
// Check to make sure it inserted its own callback.
assertFalse("The callbacks should NOT match", //$NON-NLS-1$
operationListCaptor.getValue().get(0).getCallback().equals(mockCallbackList1));
assertFalse("The callbacks should NOT match", //$NON-NLS-1$
operationListCaptor.getValue().get(1).getCallback().equals(mockCallbackList2));
// There should be only be two items in the list.
assertEquals("There should be two items", 2, operationListCaptor.getValue().size()); //$NON-NLS-1$
List<VdcReturnValueBase> resultList1 = new ArrayList<>();
List<VdcReturnValueBase> resultList2 = new ArrayList<>();
VdcReturnValueBase result1 = new VdcReturnValueBase();
VdcReturnValueBase result2 = new VdcReturnValueBase();
resultList1.add(result1);
resultList2.add(result2);
List<VdcOperation> captured1List = new ArrayList<>();
captured1List.add(operationListCaptor.getValue().get(0));
List<VdcOperation> captured2List = new ArrayList<>();
captured2List.add(operationListCaptor.getValue().get(1));
operationListCaptor.getValue().get(0).getCallback().onSuccess(captured1List, resultList1);
verify(mockCallbackList1).onSuccess(testOperation1List, resultList1);
operationListCaptor.getValue().get(1).getCallback().onSuccess(captured2List, resultList2);
}
}