Lior Vernia has posted comments on this change.

Change subject: webadmin: fluent UiAction
......................................................................


Patch Set 25:

(18 comments)

https://gerrit.ovirt.org/#/c/36848/25/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/action/UiAction.java
File 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/action/UiAction.java:

Line 173:         return name;
Line 174:     }
Line 175: 
Line 176:     void tryToFinalize(boolean handleErrors) {
Line 177:         if (actionFlowState.isAllDone() && 
actionFlowState.isStartedProgress()) {
I think only model.stopProgress() should depend on whether 
actionFlowState.isStartedProgress() - not the other stuff here like 
handleErrors() and running of the final action.
Line 178:             model.stopProgress();
Line 179: 
Line 180:             if (handleErrors) {
Line 181:                 handleErrors();


https://gerrit.ovirt.org/#/c/36848/25/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/AsyncUiActionTest.java
File 
frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/AsyncUiActionTest.java:

Line 85:         assertFinishedSuccessfully(actions);
Line 86:     }
Line 87: 
Line 88:     @Test
Line 89:     public void runNextActionFlowWithLastActionFailureTest() {
How about a test where the first action fails, which makes sure the second one 
isn't run?
Line 90:         List<UiAction> actions = runNextActionFlowCommon(false);
Line 91:         assertFinishedWithFailures(actions, 1);
Line 92:     }
Line 93: 


Line 96:         ActionFlowState flowState = 
actions.get(0).getActionFlowState();
Line 97: 
Line 98:         verifyRunActionAndExecuteCallbacksRandomly(true, flowState, 1);
Line 99:         List<C> callbacks = verfifyRunAction(2);
Line 100:         executeCallbacks(lastSuccess, flowState, 
callbacks.subList(callbacks.size() - 1, callbacks.size()));
This code REALLY isn't clear - it took me a very long time to figure out that 
since the next action is only called from the first's callback, the original 
call to verify...() didn't include all those checks. There has to be a better 
way to write this.
Line 101: 
Line 102:         return actions;
Line 103:     }
Line 104: 


Line 109:         ActionFlowState flowState = 
actions.get(0).getActionFlowState();
Line 110: 
Line 111:         verifyRunActionAndExecuteCallbacksRandomly(true, flowState, 
2);
Line 112:         List<C> callbacks = verfifyRunAction(4);
Line 113:         executeCallbacks(true, flowState, 
callbacks.subList(callbacks.size() - 2, callbacks.size()));
Same comment as above.
Line 114: 
Line 115:         assertFinishedSuccessfully(actions);
Line 116:     }
Line 117: 


Line 117: 
Line 118:     @Test
Line 119:     public void runMixedActionFlowWithFailureOnIndependentAction() {
Line 120:         // action1.and(action2).next(action3).and(action4)
Line 121:         // action1 has an error- all the flow will be executed
As above, a more interesting case is if action1 also has a next action.
Line 122: 
Line 123:         List<UiAction> actions = runActionFlow(ActionType.parallel, 
ActionType.next, ActionType.parallel);
Line 124:         ActionFlowState flowState = 
actions.get(0).getActionFlowState();
Line 125: 


Line 131:         // execute action2 callback
Line 132:         executeCallbacks(true, flowState, callbacks.subList(0, 1));
Line 133: 
Line 134:         // verify action3 and action4 were also executed
Line 135:         callbacks = verfifyRunAction(4);
Same as before - it's very hard to follow what you're validating.
Line 136: 
Line 137:         // executed the callbacks of action3 and action4
Line 138:         executeCallbacks(true, flowState, 
callbacks.subList(callbacks.size() - 2, callbacks.size()));
Line 139: 


Line 164:     protected abstract void 
verifyRunActionAndExecuteCallbacksRandomly(boolean success,
Line 165:             ActionFlowState flowState,
Line 166:             int exepectedNumOfRunActionExecutions);
Line 167: 
Line 168:     protected abstract List<C> verfifyRunAction(int 
exepectedNumOfRunActionExecutions);
verfify? :)


https://gerrit.ovirt.org/#/c/36848/25/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/SyncUiActionTest.java
File 
frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/SyncUiActionTest.java:

Line 88:     public void shouldExecuteTest() {
Line 89:         UiAction action = new SyncUiAction(model, "test") { 
//$NON-NLS-1$
Line 90:                     @Override
Line 91:                     protected void onActionExecute() {
Line 92:                         assertTrue(false);
Maybe call Mockito's fail() instead?
Line 93:                     }
Line 94: 
Line 95:                     @Override
Line 96:                     protected boolean shouldExecute() {


Line 121:         SimpleAction finalAction = new SimpleAction() {
Line 122: 
Line 123:             @Override
Line 124:             public void execute() {
Line 125:                 // Do nothing
Similarly to the above case, maybe call fail() to also mark this as a piece of 
code that shouldn't be reached?
Line 126:             }
Line 127:         };
Line 128:         action1.onAllExecutionsFinish(finalAction);
Line 129:         action2.onAllExecutionsFinish(finalAction);


https://gerrit.ovirt.org/#/c/36848/25/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/UiActionBaseTest.java
File 
frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/UiActionBaseTest.java:

Line 54:         int numOfProgressInteractions = shouldCallProgressActions ? 1 
: 0;
Line 55:         verify(model, 
times(numOfProgressInteractions)).startProgress(any(String.class));
Line 56:         verify(model, times(numOfProgressInteractions)).stopProgress();
Line 57: 
Line 58:         UiAction previousAction = null;
The test in this block is actually quite important, and I think should be 
extracted to a different method, e.g. assertStateConsistent().

I would run it not only if all actions succeeded, but also if there were 
failures, in which case I'd only care to verify that all succeeded actions 
share the same state object (why? for example getFlowState() assumes this is 
the case, even if there were failures). So maybe implement it in a public 
method and annotate it with @After.

This would require you to somehow mark individual actions as succeeded - this 
can be done by either spying on the tested action objects or extending the 
actions using special test classes. Or whatever other way you come up with...
Line 59:         for (UiAction action : actions) {
Line 60:             if (previousAction != null) {
Line 61:                 assertSame(previousAction.getActionFlowState(), 
action.getActionFlowState());
Line 62:             }


https://gerrit.ovirt.org/#/c/36848/25/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/UiVdcActionTest.java
File 
frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/UiVdcActionTest.java:

Line 20: @RunWith(MockitoJUnitRunner.class)
Line 21: public class UiVdcActionTest extends 
AsyncUiActionTest<IFrontendActionAsyncCallback> {
Line 22: 
Line 23:     @Test
Line 24:     public void runNextActionFlowWithFirstActionFailureTest() {
There's a similar test in UiVdcMultipleActionTest - can't they be unified and 
moved up into AsyncUiActionTest? Actually related to a comment I put there.
Line 25:         List<UiAction> actions = runActionFlow(ActionType.next);
Line 26:         ActionFlowState flowState = 
actions.get(0).getActionFlowState();
Line 27: 
Line 28:         verifyRunActionAndExecuteCallbacksRandomly(false, flowState, 
1);


Line 32:         
assertFinishedWithFailures(Collections.singletonList(actions.get(0)), 1);
Line 33:     }
Line 34: 
Line 35:     @Test
Line 36:     public void runMixedActionFlowWithFailureOnDependentAction() {
Same question.
Line 37:         // action1.and(action2).next(action3).and(action4)
Line 38:         // action1 and action 2 has failure -> action3 and action4 
won't be executed
Line 39: 
Line 40:         List<UiAction> actions = runActionFlow(ActionType.parallel, 
ActionType.next, ActionType.parallel);


Line 52:         action.runAction();
Line 53: 
Line 54:         verifyRunActionAndExecuteCallbacksRandomly(false, 
action.getActionFlowState(), 1, true);
Line 55: 
Line 56:         assertFinishedSuccessfully(Collections.singletonList(action));
This is weird for two reasons:

1. You're testing that the error dialog is shown yet you expect no errors?

2. Where do you actually verify that the mocked frontend tried to open an error 
dialog or something of the sort? It's quite possible that this does happen but 
I didn't research deep enough, just wanted to make sure it happens.
Line 57:     }
Line 58: 
Line 59:     @Override
Line 60:     protected UiVdcAction createAction() {


Line 60:     protected UiVdcAction createAction() {
Line 61:         return new UiVdcAction(ACTION_TYPE, new 
VdcActionParametersBase(), model);
Line 62:     }
Line 63: 
Line 64:     private UiVdcAction createAction(boolean showErrorDialog) {
You don't actually use the argument here - either rename the method or pass 
showErrorDialog to the UiVdcAction constructor instead of true.
Line 65:         return new UiVdcAction(ACTION_TYPE, new 
VdcActionParametersBase(), model, true);
Line 66:     }
Line 67: 
Line 68:     private void verifyRunActionAndExecuteCallbacksRandomly(boolean 
success,


Line 97:     }
Line 98: 
Line 99:     private List<IFrontendActionAsyncCallback> verfifyRunAction(int 
exepectedNumOfRunActionExecutions,
Line 100:             boolean showErrorDialog) {
Line 101:         verify(frontend, 
times(exepectedNumOfRunActionExecutions)).runAction(eq(ACTION_TYPE),
What is the benefit of using eq() over passing ACTION_TYPE itself? Same 
question about showErrorDialog below.
Line 102:                 any(VdcActionParametersBase.class),
Line 103:                 callbackCaptor.capture(),
Line 104:                 eq(showErrorDialog));
Line 105:         List<IFrontendActionAsyncCallback> callbacks = 
callbackCaptor.getAllValues();


https://gerrit.ovirt.org/#/c/36848/25/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/UiVdcMultipleActionTest.java
File 
frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/action/UiVdcMultipleActionTest.java:

Line 48:         assertFinishedWithFailures(actions.subList(0, 2), 2);
Line 49:     }
Line 50: 
Line 51:     @Test
Line 52:     public void waitForResultTest() {
Shouldn't this (or another test) verify that a subsequent action is run despite 
of the failure?
Line 53:         UiAction action = createAction(true, true);
Line 54:         action.runAction();
Line 55: 
Line 56:         verifyRunActionAndExecuteCallbacksRandomly(false, 
action.getActionFlowState(), 1, true);


Line 59:     }
Line 60: 
Line 61:     @Test
Line 62:     public void dontRunNextInCaseOfErrorTest() {
Line 63:         UiAction action1 = createAction(false, false);
Do you actually care whether the first parameter is false or true? Shouldn't 
the same behavior be expected whether the failure is on canDoAction() or upon 
execution? If so, you can pass a random boolean instead.
Line 64:         UiAction action2 = createAction();
Line 65:         action1.then(action2);
Line 66:         action1.runAction();
Line 67: 


Line 139:     }
Line 140: 
Line 141:     private List<IFrontendMultipleActionAsyncCallback> 
verfifyRunAction(int exepectedNumOfRunActionExecutions,
Line 142:             boolean waitForResult) {
Line 143:         verify(frontend, 
times(exepectedNumOfRunActionExecutions)).runMultipleAction(eq(ACTION_TYPE),
Same questions as in UiVdcAction concerning the usage of eq() here and below.
Line 144:                 anyListOf(VdcActionParametersBase.class),
Line 145:                 callbackCaptor.capture(),
Line 146:                 eq(false),
Line 147:                 eq(waitForResult));


-- 
To view, visit https://gerrit.ovirt.org/36848
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I262282d00bbb16a65f36a2463d3ffe8dbf6594c6
Gerrit-PatchSet: 25
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Alona Kaplan <alkap...@redhat.com>
Gerrit-Reviewer: Alona Kaplan <alkap...@redhat.com>
Gerrit-Reviewer: Lior Vernia <lver...@redhat.com>
Gerrit-Reviewer: automat...@ovirt.org
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: Yes
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to