2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.vid.job.command;
23 import static java.util.Collections.emptyList;
24 import static org.mockito.AdditionalAnswers.returnsFirstArg;
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.Mockito.RETURNS_MOCKS;
27 import static org.mockito.Mockito.doAnswer;
28 import static org.mockito.Mockito.eq;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.when;
31 import static org.onap.vid.job.command.ResourceCommandKt.ACTION_PHASE;
32 import static org.onap.vid.job.command.ResourceCommandKt.INTERNAL_STATE;
33 import static org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator.createGroup;
34 import static org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator.createMember;
35 import static org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator.createNetwork;
36 import static org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator.createService;
37 import static org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator.createVfModule;
38 import static org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator.createVnf;
39 import static org.onap.vid.model.Action.Create;
40 import static org.onap.vid.model.Action.Delete;
41 import static org.onap.vid.model.Action.None;
42 import static org.onap.vid.model.Action.Resume;
43 import static org.onap.vid.model.Action.values;
44 import static org.onap.vid.utils.Logging.getMethodCallerName;
45 import static org.testng.Assert.assertNull;
46 import static org.testng.Assert.assertTrue;
47 import static org.testng.AssertJUnit.assertEquals;
48 import static org.testng.AssertJUnit.assertFalse;
50 import com.google.common.collect.ImmutableList;
51 import com.google.common.collect.ImmutableMap;
52 import java.util.Collections;
53 import java.util.HashMap;
54 import java.util.List;
56 import java.util.Optional;
57 import java.util.UUID;
58 import java.util.stream.Collectors;
59 import java.util.stream.Stream;
60 import javax.ws.rs.ProcessingException;
62 import org.jetbrains.annotations.NotNull;
63 import org.onap.vid.exceptions.AbortingException;
64 import org.onap.vid.exceptions.GenericUncheckedException;
65 import org.onap.vid.exceptions.TryAgainException;
66 import org.onap.vid.job.Job;
67 import org.onap.vid.job.JobAdapter;
68 import org.onap.vid.job.JobsBrokerService;
69 import org.onap.vid.job.NextCommand;
70 import org.onap.vid.job.impl.JobSharedData;
71 import org.onap.vid.model.Action;
72 import org.onap.vid.model.serviceInstantiation.BaseResource;
73 import org.onap.vid.model.serviceInstantiation.InstanceGroup;
74 import org.onap.vid.model.serviceInstantiation.InstanceGroupMember;
75 import org.onap.vid.model.serviceInstantiation.Network;
76 import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
77 import org.onap.vid.model.serviceInstantiation.VfModule;
78 import org.onap.vid.model.serviceInstantiation.Vnf;
79 import org.onap.vid.mso.RestMsoImplementation;
80 import org.onap.vid.mso.model.ModelInfo;
81 import org.springframework.http.HttpMethod;
82 import org.testng.annotations.DataProvider;
83 import org.testng.annotations.Test;
85 public class ResourceCommandTest {
87 public static class MockCommand extends ResourceCommand {
89 public MockCommand(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus) {
90 this(mockState, mockPhase, mockedJobStatus, false);
93 public MockCommand(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean lateInit) {
95 mock(RestMsoImplementation.class, RETURNS_MOCKS),
96 mock(InProgressStatusService.class),
97 mock(MsoResultHandlerService.class, RETURNS_MOCKS),
98 mock(WatchChildrenJobsBL.class),
99 mock(JobsBrokerService.class, RETURNS_MOCKS),
100 mock(JobAdapter.class, RETURNS_MOCKS));
101 this.mockedJobStatus = mockedJobStatus;
102 this.mockState = mockState;
103 this.mockPhase = mockPhase;
107 when(this.getWatchChildrenJobsBL().cumulateJobStatus(any(), any())).thenReturn(mockedJobStatus);
110 protected void init() {
111 if (mockState == InternalState.INITIAL) {
112 init(mock(JobSharedData.class), Collections.emptyMap());
114 init(mock(JobSharedData.class), ImmutableMap.of(INTERNAL_STATE, mockState.name(), ACTION_PHASE, mockPhase.name()));
118 private final Job.JobStatus mockedJobStatus;
119 private final InternalState mockState;
120 private final Action mockPhase;
125 public Job.JobStatus createChildren() {
126 if (mockState == InternalState.CREATING_CHILDREN || (mockState == InternalState.INITIAL && mockPhase== Delete))
127 return mockedJobStatus;
128 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
131 protected Job.JobStatus mockedStatusOrThrow(InternalState expectedState) {
132 if (mockState == expectedState)
133 return mockedJobStatus;
134 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
137 protected MsoRestCallPlan mockedPlanOrThrow(InternalState expectedState) {
138 if (mockState == expectedState)
139 return new MsoRestCallPlan(HttpMethod.POST, "path", Optional.empty(), Optional.empty(), "nothing");
140 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
145 public MsoRestCallPlan planCreateMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId, String testApi) {
146 return mockedPlanOrThrow(InternalState.CREATE_MYSELF);
151 public MsoRestCallPlan planDeleteMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) {
152 return mockedPlanOrThrow(InternalState.DELETE_MYSELF);
156 public static class MockCommandTestingStateMachine extends MockCommand {
158 private final JobSharedData sharedData;
159 private final boolean isDescendantHasAction;
161 public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf) {
162 this(mockState, mockPhase, mockedJobStatus, mockedNeedToDeleteMySelf, false, true);
165 public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf, boolean isService, boolean isDescendantHasAction) {
166 super(mockState, mockPhase, mockedJobStatus, true);
167 this.mockedNeedToDeleteMySelf = mockedNeedToDeleteMySelf;
168 this.isService = isService;
169 this.sharedData = mock(JobSharedData.class, RETURNS_MOCKS);
170 this.isDescendantHasAction = isDescendantHasAction;
174 protected final boolean mockedNeedToDeleteMySelf;
175 private final boolean isService;
179 public Job.JobStatus inProgress() {
180 return mockedStatusOrThrow(InternalState.IN_PROGRESS);
185 public Job.JobStatus watchChildren() {
186 return mockedStatusOrThrow(InternalState.WATCHING);
190 public boolean isNeedToDeleteMyself() {
191 return mockedNeedToDeleteMySelf;
195 protected boolean isServiceCommand() {
200 public JobSharedData getSharedData() {
205 protected boolean isDescendantHasAction(@NotNull Action phase) {
206 return isDescendantHasAction;
211 public static Object[][] nextStateDeletePhaseProvider() {
212 return new Object[][]{
213 {InternalState.CREATING_CHILDREN, Job.JobStatus.COMPLETED, InternalState.WATCHING},
214 {InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF},
215 {InternalState.WATCHING, Job.JobStatus.IN_PROGRESS, InternalState.WATCHING},
216 {InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING},
217 {InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS},
218 {InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, InternalState.TERMINAL},
219 {InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS},
220 {InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.IN_PROGRESS},
224 @Test(dataProvider = "nextStateDeletePhaseProvider")
225 public void whenCalcNextStateDeletePhase_expectedStateIsReturned(
226 InternalState internalState, Job.JobStatus jobStatus, InternalState expectedState) {
228 //there is no meaning to the constructor inputs here
229 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Delete, Job.JobStatus.FAILED, true);
230 assertEquals(expectedState, underTest.calcNextStateDeletePhase(jobStatus, internalState));
234 public void whenNoNeedToDeleteMyself_internalStateMovesFromWatchingToTerminal() {
235 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Delete, Job.JobStatus.COMPLETED, false);
236 assertEquals(InternalState.TERMINAL, underTest.calcNextStateDeletePhase(Job.JobStatus.COMPLETED, InternalState.WATCHING));
240 public static Object[][] testShallStopJobDataProvider() {
241 return new Object[][]{
242 {Job.JobStatus.IN_PROGRESS, None, false, false},
243 {Job.JobStatus.COMPLETED_WITH_NO_ACTION, None, false, false},
244 {Job.JobStatus.COMPLETED, None, false, false},
245 {Job.JobStatus.FAILED, None, false, true},
246 {Job.JobStatus.COMPLETED_WITH_ERRORS, None, false, true},
247 {Job.JobStatus.COMPLETED_WITH_ERRORS, None, true, false},
248 {Job.JobStatus.FAILED, None, true, false},
249 {Job.JobStatus.FAILED, Delete, true, true},
250 {Job.JobStatus.FAILED, Create, true, true},
255 @Test(dataProvider = "testShallStopJobDataProvider")
256 public void testShallStopJob(Job.JobStatus jobStatus, Action action, boolean isService, boolean expectedResult) {
257 //in this test, there is no meaning to constructor parameters besides isService
258 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Delete, Job.JobStatus.COMPLETED, false, isService, true);
260 BaseResource mockedRequest = mock(BaseResource.class);
261 when(underTest.getSharedData().getRequest()).thenReturn(mockedRequest);
262 when(mockedRequest.getAction()).thenReturn(action);
264 assertEquals(expectedResult, underTest.shallStopJob(jobStatus));
267 public static class FakeResourceCreator {
269 public static<T> Map<String, T> convertToMap(List<T> list) {
273 return list.stream().collect(Collectors.toMap(x-> UUID.randomUUID().toString(), x->x));
276 static ServiceInstantiation createService(List<Vnf> vnfs, List<Network> networks, List<InstanceGroup> vnfGroups) {
277 return new ServiceInstantiation(mock(ModelInfo.class), null, null, null, null, null, null, null, null, null, null, null, null, null, null,
279 convertToMap(networks),
280 convertToMap(vnfGroups),
282 null, false, 1, false,false,null, null, null, null, null, null, null);
285 public static ServiceInstantiation createServiceWith2InstancesInEachLevel(Action action) {
286 return createService(
288 createVnf(ImmutableList.of(createVfModule(action), createVfModule(action)), action),
289 createVnf(ImmutableList.of(createVfModule(action), createVfModule(action)), action)),
291 createNetwork(action),
292 createNetwork(action)),
294 createGroup(ImmutableList.of(createMember(action), createMember(action)), action),
295 createGroup(ImmutableList.of(createMember(action), createMember(action)), action))
299 static InstanceGroup createGroup(List<InstanceGroupMember> groupMembers, Action action) {
300 return new InstanceGroup(mock(ModelInfo.class), null, action.name(), false, null, convertToMap(groupMembers), null, null, null,
304 static InstanceGroupMember createMember(Action action) {
305 return new InstanceGroupMember(null, action.toString(), null, null, null, null);
308 static Vnf createVnf(List<VfModule> vfModules, Action action) {
309 Map<String, Map<String, VfModule>> vfModulesMap = new HashMap<>();
310 vfModulesMap.put("abc",convertToMap(vfModules));
312 return new Vnf(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null, vfModulesMap, null, null, null,
316 static Vnf createVnf(Action action) {
317 return new Vnf(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null,null, null, null, null,
321 static VfModule createVfModule(Action action) {
322 return new VfModule(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null,
323 false, false, null, null, null, null, null, null, null);
326 static Network createNetwork(Action action) {
327 return new Network(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null, null, null, null,
333 public static Object[][] testIsDescendantHasActionDataProvider() {
334 return new Object[][]{
335 {"empty service", Create, false, createService(emptyList(), emptyList(), emptyList())},
336 {"instance group with None", Create, false, createService(emptyList(), emptyList(), ImmutableList.of(createGroup(emptyList(), None)))},
337 {"instance group with Create", Create, true, createService(emptyList(), emptyList(), ImmutableList.of(createGroup(emptyList(), Create)))},
338 {"instance group None + member Delete", Delete, true, createService(emptyList(), emptyList(), ImmutableList.of(createGroup(ImmutableList.of(createMember(Delete)), None)))},
339 {"instance group None + member Create", Delete, false, createService(emptyList(), emptyList(), ImmutableList.of(createGroup(ImmutableList.of(createMember(Create)), None)))},
340 {"instance group None + member Create + member Delete", Delete, true,
341 createService(emptyList(), emptyList(), ImmutableList.of(createGroup(ImmutableList.of(createMember(Create), createMember(Delete)), None)))},
342 {"vnf Create", Delete, false, createService(ImmutableList.of(createVnf(emptyList(), Create)), emptyList(),emptyList())},
343 {"vnf Create", Create, true, createService(ImmutableList.of(createVnf(emptyList(), Create)), emptyList(),emptyList())},
344 {"vnf Create null VfModules internal map", Create, false, createService(ImmutableList.of(createVnf(null, Delete)), emptyList(),emptyList())},
345 {"vnf Delete with null VfModules", Create, false, createService(ImmutableList.of(createVnf(Delete)), emptyList(),emptyList())},
346 {"vnf None + VfModule Create", Create, true, createService(ImmutableList.of(createVnf(ImmutableList.of(createVfModule(Create)), None)), emptyList(),emptyList())},
347 {"vnf None + VfModule None", Create, false, createService(ImmutableList.of(createVnf(ImmutableList.of(createVfModule(None)), None)), emptyList(),emptyList())},
348 {"network Create", Create, true, createService(emptyList(), ImmutableList.of(createNetwork(Create)), emptyList())},
349 {"network Delete", Create, false, createService(emptyList(), ImmutableList.of(createNetwork(Delete)), emptyList())},
353 @Test(dataProvider = "testIsDescendantHasActionDataProvider")
354 public void testIsDescendantHasAction(String desc, Action action, boolean expectedResult, BaseResource request) {
355 //in this test, there is no meaning to constructor parameters
356 MockCommand underTest = new MockCommand(InternalState.WATCHING, Delete, Job.JobStatus.COMPLETED);
357 assertEquals(expectedResult, underTest.isDescendantHasAction(request, action));
361 public static Object[][] testCallDataProvider() {
362 return new Object[][]{
363 {"initial state with successful creating children" ,InternalState.INITIAL, Job.JobStatus.COMPLETED, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
364 {"initial state with failed creating children", InternalState.INITIAL, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
365 {"watching state with children still in progress" ,InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
366 {"watching state with children that completed with errors" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_ERRORS, null, Job.JobStatus.COMPLETED_WITH_ERRORS},
367 {"watching state with children that completed with no action" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_NO_ACTION, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS},
368 {"watching state with children that has completed" ,InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS},
369 {"mso call state that failed" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
370 //TODO handle AAI get unique name state {"mso call state that still in progress" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED, false},
371 {"mso call state that success" ,InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
372 {"in progress return in progress" ,InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
373 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.PAUSE, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
374 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.STOPPED, null, Job.JobStatus.STOPPED},
375 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
376 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, null, Job.JobStatus.COMPLETED},
381 @Test(dataProvider = "testCallDataProvider")
382 public void whenCallCommandWithDeletePhase_nextJobStatusAndInternalStateAreAsExpected(
383 String description, InternalState internalState, Job.JobStatus currentStateResult,
384 InternalState expectedNextState, Job.JobStatus expectedNextStatus) {
386 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(internalState, Delete, currentStateResult, true);
387 NextCommand nextCommand = underTest.call();
388 assertEquals(expectedNextStatus, nextCommand.getStatus());
390 //expectedNextState == null means nextCommand has no real command
391 if (expectedNextState!=null) {
392 assertEquals(expectedNextState, (nextCommand.getCommand().getData().get(INTERNAL_STATE)));
393 assertFalse(nextCommand.getStatus().isFinal());
396 assertNull(nextCommand.getCommand());
397 assertTrue(nextCommand.getStatus().isFinal());
402 public static Object[][] InProgressDataProvider() {
403 return Stream.of(Job.JobStatus.values())
404 .map(status -> new Object[] { status })
405 .toArray(Object[][]::new);
408 @Test(dataProvider = "InProgressDataProvider")
409 public void whenGetResultFromMso_InProgressReturnThem(Job.JobStatus mockedJobStatus) {
410 Job.JobStatus expectedJobStatus = (mockedJobStatus== Job.JobStatus.PAUSE) ? Job.JobStatus.IN_PROGRESS : mockedJobStatus;
411 MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Delete, mockedJobStatus);
412 when(underTest.getInProgressStatusService().call(any(), any(), any())).thenReturn(mockedJobStatus);
413 assertEquals(expectedJobStatus, underTest.inProgress());
417 public static Object[][] InProgressExceptionsDataProvider() {
418 return new Object[][]{
419 {new ProcessingException(""), Job.JobStatus.IN_PROGRESS},
420 {new InProgressStatusService.BadResponseFromMso(null), Job.JobStatus.IN_PROGRESS},
421 {new GenericUncheckedException(""),Job.JobStatus.STOPPED }
425 @Test(dataProvider = "InProgressExceptionsDataProvider")
426 public void whenInProgressStatusServiceThrowException_InProgressReturnStatus(Exception exception, Job.JobStatus expectedJobStatus) {
427 MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Delete, expectedJobStatus);
428 when(underTest.getInProgressStatusService().call(any(), any(), any())).thenThrow(exception);
429 assertEquals(expectedJobStatus, underTest.inProgress());
433 public static Object[][] testIsNeedToDeleteMySelfDataProvider() {
434 return Stream.of(values())
435 .map(status -> new Object[] { status })
436 .toArray(Object[][]::new);
439 @Test(dataProvider = "testIsNeedToDeleteMySelfDataProvider")
440 public void testIsNeedToDeleteMySelf(Action action) {
441 boolean expectedResult = (action== Delete);
442 MockCommand underTest = new MockCommand(InternalState.DELETE_MYSELF, Delete, Job.JobStatus.IN_PROGRESS);
443 BaseResource mockedBaseResource = mock(BaseResource.class);
444 when(underTest.getSharedData().getRequest()).thenReturn(mockedBaseResource);
445 when(mockedBaseResource.getAction()).thenReturn(action);
446 assertEquals(expectedResult, underTest.isNeedToDeleteMyself());
450 public static Object[][] testWatchingDataProvider() {
451 return new Object[][]{
452 {"all children final, no failed child ", Job.JobStatus.COMPLETED, Job.JobStatus.COMPLETED},
453 {"all children final, there is failed child ", Job.JobStatus.COMPLETED_WITH_ERRORS, Job.JobStatus.COMPLETED_WITH_ERRORS},
454 {"not all children final", Job.JobStatus.IN_PROGRESS, Job.JobStatus.IN_PROGRESS},
458 @Test(dataProvider = "testWatchingDataProvider")
459 public void testWatching(String desc, Job.JobStatus childrenJobsStatus, Job.JobStatus expectedJobStatus) {
460 MockCommand underTest = new MockCommand(InternalState.WATCHING, Delete, Job.JobStatus.IN_PROGRESS);
461 when(underTest.getWatchChildrenJobsBL().retrieveChildrenJobsStatus(any())).thenReturn(childrenJobsStatus);
462 assertEquals(expectedJobStatus, underTest.watchChildren());
466 public static Object[][] testCalcInitialStateDataProvider() {
467 return new Object[][]{
468 {Delete, true, Delete, InternalState.CREATING_CHILDREN},
469 {Delete, false, Delete, InternalState.DELETE_MYSELF},
470 {Delete, false, Create, InternalState.TERMINAL},
471 {Delete, true, Create, InternalState.CREATING_CHILDREN},
472 {Create, true, Create, InternalState.CREATE_MYSELF},
473 {Create, false, Create, InternalState.CREATE_MYSELF},
474 {Create, false, Delete, InternalState.TERMINAL},
475 {Create, true, Delete, InternalState.CREATING_CHILDREN},
476 {Create, true, Resume, InternalState.RESUME_MYSELF},
477 {Delete, false, Resume, InternalState.TERMINAL},
481 @Test(dataProvider = "testCalcInitialStateDataProvider")
482 public void testCalcInitialState(Action phase, boolean isDescendantHasAction, Action action, InternalState expectedState) {
483 ResourceCommand underTest = mock(ResourceCommand.class);
484 when(underTest.calcInitialState(any(), any())).thenCallRealMethod();
485 when(underTest.isDescendantHasAction(eq(phase))).thenReturn(isDescendantHasAction);
486 when(underTest.getActionType()).thenReturn(action);
487 when(underTest.isNeedToDeleteMyself()).thenCallRealMethod();
488 when(underTest.isNeedToCreateMyself()).thenCallRealMethod();
489 when(underTest.isNeedToResumeMySelf()).thenCallRealMethod();
491 Map<String, String> commandData = ImmutableMap.of(INTERNAL_STATE, InternalState.INITIAL.name());
492 assertEquals(expectedState, underTest.calcInitialState(commandData, phase));
496 //throw exception when call to create children
497 //create children is just example, it could be any other method that called by ResourceCommand.invokeCommand
498 public static class MockCommandThrowExceptionOnCreateChildren extends MockCommandTestingStateMachine {
500 private final RuntimeException exceptionToThrow;
502 public MockCommandThrowExceptionOnCreateChildren(RuntimeException exceptionToThrow) {
503 super(InternalState.CREATING_CHILDREN, Delete, Job.JobStatus.COMPLETED, true);
504 this.exceptionToThrow = exceptionToThrow;
505 doAnswer(returnsFirstArg()).when(this.getWatchChildrenJobsBL()).cumulateJobStatus(any(), any());
510 public Job.JobStatus createChildren() {
511 throw exceptionToThrow;
516 public static Object[][] exceptionAndStateProvider() {
517 return new Object[][]{
518 {new TryAgainException(new Exception()), Job.JobStatus.RESOURCE_IN_PROGRESS},
519 {new AbortingException(new Exception()), Job.JobStatus.FAILED},
523 @Test(dataProvider = "exceptionAndStateProvider")
524 public void whenKnownExceptionThrownInCommandInvocation_thenStateIsAsExpected(RuntimeException exception, Job.JobStatus expectedNextStatus) {
525 MockCommandTestingStateMachine underTest = new MockCommandThrowExceptionOnCreateChildren(exception);
526 NextCommand nextCommand = underTest.call();
527 assertEquals(expectedNextStatus, nextCommand.getStatus());
531 public static Object[][] resourcePosition() {
532 return new Object[][]{
533 {1, 2, 3, ImmutableList.of(1,2,3)},
534 {null, 1, 100, ImmutableList.of(101,1,100)},
535 {null, null, null, ImmutableList.of(1,2,3)},
536 {1,2,2, ImmutableList.of(1,2,2)}
540 @Test(dataProvider = "resourcePosition")
541 public void sortChildren_sortAccordingToPosition(Integer firstPosition, Integer secondPosition, Integer thirdPosition, List<Integer> expectedPositions){
542 BaseResource mockedRequest1 = mock(BaseResource.class);
543 when(mockedRequest1.getPosition()).thenReturn(firstPosition);
544 BaseResource mockedRequest2 = mock(BaseResource.class);
545 when(mockedRequest2.getPosition()).thenReturn(secondPosition);
546 BaseResource mockedRequest3 = mock(BaseResource.class);
547 when(mockedRequest3.getPosition()).thenReturn(thirdPosition);
549 MockCommand underTest = new MockCommand(InternalState.CREATING_CHILDREN, Create, Job.JobStatus.IN_PROGRESS);
550 List<Pair<BaseResource, Integer>> sortedList = underTest.setPositionWhereIsMissing(ImmutableList.of(mockedRequest1, mockedRequest2, mockedRequest3));
552 assertEquals(sortedList.get(0).getSecond(),expectedPositions.get(0));
553 assertEquals(sortedList.get(1).getSecond(),expectedPositions.get(1));
554 assertEquals(sortedList.get(2).getSecond(),expectedPositions.get(2));