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 com.google.common.collect.ImmutableList;
24 import com.google.common.collect.ImmutableMap;
25 import org.jetbrains.annotations.NotNull;
26 import org.onap.vid.exceptions.AbortingException;
27 import org.onap.vid.exceptions.GenericUncheckedException;
28 import org.onap.vid.exceptions.TryAgainException;
29 import org.onap.vid.job.Job;
30 import org.onap.vid.job.JobAdapter;
31 import org.onap.vid.job.JobsBrokerService;
32 import org.onap.vid.job.NextCommand;
33 import org.onap.vid.job.impl.JobSharedData;
34 import org.onap.vid.model.Action;
35 import org.onap.vid.model.serviceInstantiation.*;
36 import org.onap.vid.mso.RestMsoImplementation;
37 import org.onap.vid.mso.model.ModelInfo;
38 import org.springframework.http.HttpMethod;
39 import org.testng.annotations.DataProvider;
40 import org.testng.annotations.Test;
42 import javax.ws.rs.ProcessingException;
44 import java.util.stream.Collectors;
45 import java.util.stream.Stream;
47 import static java.util.Collections.emptyList;
48 import static org.mockito.AdditionalAnswers.returnsFirstArg;
49 import static org.mockito.ArgumentMatchers.any;
50 import static org.mockito.Mockito.*;
51 import static org.onap.vid.job.command.ResourceCommandKt.ACTION_PHASE;
52 import static org.onap.vid.job.command.ResourceCommandKt.INTERNAL_STATE;
53 import static org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator.*;
54 import static org.onap.vid.model.Action.*;
55 import static org.onap.vid.utils.Logging.getMethodCallerName;
56 import static org.testng.Assert.assertNull;
57 import static org.testng.Assert.assertTrue;
58 import static org.testng.AssertJUnit.assertEquals;
59 import static org.testng.AssertJUnit.assertFalse;
61 public class ResourceCommandTest {
63 public static class MockCommand extends ResourceCommand {
65 public MockCommand(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus) {
66 this(mockState, mockPhase, mockedJobStatus, false);
69 public MockCommand(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean lateInit) {
71 mock(RestMsoImplementation.class, RETURNS_MOCKS),
72 mock(InProgressStatusService.class),
73 mock(MsoResultHandlerService.class, RETURNS_MOCKS),
74 mock(WatchChildrenJobsBL.class),
75 mock(JobsBrokerService.class, RETURNS_MOCKS),
76 mock(JobAdapter.class, RETURNS_MOCKS));
77 this.mockedJobStatus = mockedJobStatus;
78 this.mockState = mockState;
79 this.mockPhase = mockPhase;
83 when(this.getWatchChildrenJobsBL().cumulateJobStatus(any(), any())).thenReturn(mockedJobStatus);
86 protected void init() {
87 if (mockState == InternalState.INITIAL) {
88 init(mock(JobSharedData.class), Collections.emptyMap());
90 init(mock(JobSharedData.class), ImmutableMap.of(INTERNAL_STATE, mockState.name(), ACTION_PHASE, mockPhase.name()));
94 private final Job.JobStatus mockedJobStatus;
95 private final InternalState mockState;
96 private final Action mockPhase;
101 public Job.JobStatus createChildren() {
102 if (mockState == InternalState.CREATING_CHILDREN || (mockState == InternalState.INITIAL && mockPhase== Delete))
103 return mockedJobStatus;
104 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
107 protected Job.JobStatus mockedStatusOrThrow(InternalState expectedState) {
108 if (mockState == expectedState)
109 return mockedJobStatus;
110 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
113 protected MsoRestCallPlan mockedPlanOrThrow(InternalState expectedState) {
114 if (mockState == expectedState)
115 return new MsoRestCallPlan(HttpMethod.POST, "path", Optional.empty(), Optional.empty(), "nothing");
116 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
121 public MsoRestCallPlan planCreateMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId, String testApi) {
122 return mockedPlanOrThrow(InternalState.CREATE_MYSELF);
127 public MsoRestCallPlan planDeleteMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) {
128 return mockedPlanOrThrow(InternalState.DELETE_MYSELF);
132 public static class MockCommandTestingStateMachine extends MockCommand {
134 private final JobSharedData sharedData;
135 private final boolean isDescendantHasAction;
137 public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf) {
138 this(mockState, mockPhase, mockedJobStatus, mockedNeedToDeleteMySelf, false, true);
141 public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf, boolean isService, boolean isDescendantHasAction) {
142 super(mockState, mockPhase, mockedJobStatus, true);
143 this.mockedNeedToDeleteMySelf = mockedNeedToDeleteMySelf;
144 this.isService = isService;
145 this.sharedData = mock(JobSharedData.class, RETURNS_MOCKS);
146 this.isDescendantHasAction = isDescendantHasAction;
150 protected final boolean mockedNeedToDeleteMySelf;
151 private final boolean isService;
155 public Job.JobStatus inProgress() {
156 return mockedStatusOrThrow(InternalState.IN_PROGRESS);
161 public Job.JobStatus watchChildren() {
162 return mockedStatusOrThrow(InternalState.WATCHING);
166 public boolean isNeedToDeleteMyself() {
167 return mockedNeedToDeleteMySelf;
171 protected boolean isServiceCommand() {
176 public JobSharedData getSharedData() {
181 protected boolean isDescendantHasAction(@NotNull Action phase) {
182 return isDescendantHasAction;
187 public static Object[][] nextStateDeletePhaseProvider() {
188 return new Object[][]{
189 {InternalState.CREATING_CHILDREN, Job.JobStatus.COMPLETED, InternalState.WATCHING},
190 {InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF},
191 {InternalState.WATCHING, Job.JobStatus.IN_PROGRESS, InternalState.WATCHING},
192 {InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING},
193 {InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS},
194 {InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, InternalState.TERMINAL},
195 {InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS},
196 {InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.IN_PROGRESS},
200 @Test(dataProvider = "nextStateDeletePhaseProvider")
201 public void whenCalcNextStateDeletePhase_expectedStateIsReturned(
202 InternalState internalState, Job.JobStatus jobStatus, InternalState expectedState) {
204 //there is no meaning to the constructor inputs here
205 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Delete, Job.JobStatus.FAILED, true);
206 assertEquals(expectedState, underTest.calcNextStateDeletePhase(jobStatus, internalState));
210 public void whenNoNeedToDeleteMyself_internalStateMovesFromWatchingToTerminal() {
211 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Delete, Job.JobStatus.COMPLETED, false);
212 assertEquals(InternalState.TERMINAL, underTest.calcNextStateDeletePhase(Job.JobStatus.COMPLETED, InternalState.WATCHING));
216 public static Object[][] testShallStopJobDataProvider() {
217 return new Object[][]{
218 {Job.JobStatus.IN_PROGRESS, None, false, false},
219 {Job.JobStatus.COMPLETED_WITH_NO_ACTION, None, false, false},
220 {Job.JobStatus.COMPLETED, None, false, false},
221 {Job.JobStatus.FAILED, None, false, true},
222 {Job.JobStatus.COMPLETED_WITH_ERRORS, None, false, true},
223 {Job.JobStatus.COMPLETED_WITH_ERRORS, None, true, false},
224 {Job.JobStatus.FAILED, None, true, false},
225 {Job.JobStatus.FAILED, Delete, true, true},
226 {Job.JobStatus.FAILED, Create, true, true},
231 @Test(dataProvider = "testShallStopJobDataProvider")
232 public void testShallStopJob(Job.JobStatus jobStatus, Action action, boolean isService, boolean expectedResult) {
233 //in this test, there is no meaning to constructor parameters besides isService
234 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Delete, Job.JobStatus.COMPLETED, false, isService, true);
236 BaseResource mockedRequest = mock(BaseResource.class);
237 when(underTest.getSharedData().getRequest()).thenReturn(mockedRequest);
238 when(mockedRequest.getAction()).thenReturn(action);
240 assertEquals(expectedResult, underTest.shallStopJob(jobStatus));
243 public static class FakeResourceCreator {
245 public static<T> Map<String, T> convertToMap(List<T> list) {
249 return list.stream().collect(Collectors.toMap(x-> UUID.randomUUID().toString(), x->x));
252 static ServiceInstantiation createService(List<Vnf> vnfs, List<Network> networks, List<InstanceGroup> vnfGroups) {
253 return new ServiceInstantiation(mock(ModelInfo.class), null, null, null, null, null, null, null, null, null, null, null, null, null, null,
255 convertToMap(networks),
256 convertToMap(vnfGroups),
258 null, false, 1, false,false,null, null, null, null, null, null, null);
261 public static ServiceInstantiation createServiceWith2InstancesInEachLevel(Action action) {
262 return createService(
264 createVnf(ImmutableList.of(createVfModule(action), createVfModule(action)), action),
265 createVnf(ImmutableList.of(createVfModule(action), createVfModule(action)), action)),
267 createNetwork(action),
268 createNetwork(action)),
270 createGroup(ImmutableList.of(createMember(action), createMember(action)), action),
271 createGroup(ImmutableList.of(createMember(action), createMember(action)), action))
275 static InstanceGroup createGroup(List<InstanceGroupMember> groupMembers, Action action) {
276 return new InstanceGroup(mock(ModelInfo.class), null, action.name(), false, null, convertToMap(groupMembers), null, null, null,
280 static InstanceGroupMember createMember(Action action) {
281 return new InstanceGroupMember(null, action.toString(), null, null, null, null);
284 static Vnf createVnf(List<VfModule> vfModules, Action action) {
285 Map<String, Map<String, VfModule>> vfModulesMap = new HashMap<>();
286 vfModulesMap.put("abc",convertToMap(vfModules));
288 return new Vnf(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null, vfModulesMap, null, null, null,
292 static Vnf createVnf(Action action) {
293 return new Vnf(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null,null, null, null, null,
297 static VfModule createVfModule(Action action) {
298 return new VfModule(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, false, false, null, null, null, null,
302 static Network createNetwork(Action action) {
303 return new Network(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null, null, null, null,
309 public static Object[][] testIsDescendantHasActionDataProvider() {
310 return new Object[][]{
311 {"empty service", Create, false, createService(emptyList(), emptyList(), emptyList())},
312 {"instance group with None", Create, false, createService(emptyList(), emptyList(), ImmutableList.of(createGroup(emptyList(), None)))},
313 {"instance group with Create", Create, true, createService(emptyList(), emptyList(), ImmutableList.of(createGroup(emptyList(), Create)))},
314 {"instance group None + member Delete", Delete, true, createService(emptyList(), emptyList(), ImmutableList.of(createGroup(ImmutableList.of(createMember(Delete)), None)))},
315 {"instance group None + member Create", Delete, false, createService(emptyList(), emptyList(), ImmutableList.of(createGroup(ImmutableList.of(createMember(Create)), None)))},
316 {"instance group None + member Create + member Delete", Delete, true,
317 createService(emptyList(), emptyList(), ImmutableList.of(createGroup(ImmutableList.of(createMember(Create), createMember(Delete)), None)))},
318 {"vnf Create", Delete, false, createService(ImmutableList.of(createVnf(emptyList(), Create)), emptyList(),emptyList())},
319 {"vnf Create", Create, true, createService(ImmutableList.of(createVnf(emptyList(), Create)), emptyList(),emptyList())},
320 {"vnf Create null VfModules internal map", Create, false, createService(ImmutableList.of(createVnf(null, Delete)), emptyList(),emptyList())},
321 {"vnf Delete with null VfModules", Create, false, createService(ImmutableList.of(createVnf(Delete)), emptyList(),emptyList())},
322 {"vnf None + VfModule Create", Create, true, createService(ImmutableList.of(createVnf(ImmutableList.of(createVfModule(Create)), None)), emptyList(),emptyList())},
323 {"vnf None + VfModule None", Create, false, createService(ImmutableList.of(createVnf(ImmutableList.of(createVfModule(None)), None)), emptyList(),emptyList())},
324 {"network Create", Create, true, createService(emptyList(), ImmutableList.of(createNetwork(Create)), emptyList())},
325 {"network Delete", Create, false, createService(emptyList(), ImmutableList.of(createNetwork(Delete)), emptyList())},
329 @Test(dataProvider = "testIsDescendantHasActionDataProvider")
330 public void testIsDescendantHasAction(String desc, Action action, boolean expectedResult, BaseResource request) {
331 //in this test, there is no meaning to constructor parameters
332 MockCommand underTest = new MockCommand(InternalState.WATCHING, Delete, Job.JobStatus.COMPLETED);
333 assertEquals(expectedResult, underTest.isDescendantHasAction(request, action));
337 public static Object[][] testCallDataProvider() {
338 return new Object[][]{
339 {"initial state with successful creating children" ,InternalState.INITIAL, Job.JobStatus.COMPLETED, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
340 {"initial state with failed creating children", InternalState.INITIAL, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
341 {"watching state with children still in progress" ,InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
342 {"watching state with children that completed with errors" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_ERRORS, null, Job.JobStatus.COMPLETED_WITH_ERRORS},
343 {"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},
344 {"watching state with children that has completed" ,InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS},
345 {"mso call state that failed" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
346 //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},
347 {"mso call state that success" ,InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
348 {"in progress return in progress" ,InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
349 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.PAUSE, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
350 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.STOPPED, null, Job.JobStatus.STOPPED},
351 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
352 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, null, Job.JobStatus.COMPLETED},
357 @Test(dataProvider = "testCallDataProvider")
358 public void whenCallCommandWithDeletePhase_nextJobStatusAndInternalStateAreAsExpected(
359 String description, InternalState internalState, Job.JobStatus currentStateResult,
360 InternalState expectedNextState, Job.JobStatus expectedNextStatus) {
362 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(internalState, Delete, currentStateResult, true);
363 NextCommand nextCommand = underTest.call();
364 assertEquals(expectedNextStatus, nextCommand.getStatus());
366 //expectedNextState == null means nextCommand has no real command
367 if (expectedNextState!=null) {
368 assertEquals(expectedNextState, (nextCommand.getCommand().getData().get(INTERNAL_STATE)));
369 assertFalse(nextCommand.getStatus().isFinal());
372 assertNull(nextCommand.getCommand());
373 assertTrue(nextCommand.getStatus().isFinal());
378 public static Object[][] InProgressDataProvider() {
379 return Stream.of(Job.JobStatus.values())
380 .map(status -> new Object[] { status })
381 .toArray(Object[][]::new);
384 @Test(dataProvider = "InProgressDataProvider")
385 public void whenGetResultFromMso_InProgressReturnThem(Job.JobStatus mockedJobStatus) {
386 Job.JobStatus expectedJobStatus = (mockedJobStatus== Job.JobStatus.PAUSE) ? Job.JobStatus.IN_PROGRESS : mockedJobStatus;
387 MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Delete, mockedJobStatus);
388 when(underTest.getInProgressStatusService().call(any(), any(), any())).thenReturn(mockedJobStatus);
389 assertEquals(expectedJobStatus, underTest.inProgress());
393 public static Object[][] InProgressExceptionsDataProvider() {
394 return new Object[][]{
395 {new ProcessingException(""), Job.JobStatus.IN_PROGRESS},
396 {new InProgressStatusService.BadResponseFromMso(null), Job.JobStatus.IN_PROGRESS},
397 {new GenericUncheckedException(""),Job.JobStatus.STOPPED }
401 @Test(dataProvider = "InProgressExceptionsDataProvider")
402 public void whenInProgressStatusServiceThrowException_InProgressReturnStatus(Exception exception, Job.JobStatus expectedJobStatus) {
403 MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Delete, expectedJobStatus);
404 when(underTest.getInProgressStatusService().call(any(), any(), any())).thenThrow(exception);
405 assertEquals(expectedJobStatus, underTest.inProgress());
409 public static Object[][] testIsNeedToDeleteMySelfDataProvider() {
410 return Stream.of(values())
411 .map(status -> new Object[] { status })
412 .toArray(Object[][]::new);
415 @Test(dataProvider = "testIsNeedToDeleteMySelfDataProvider")
416 public void testIsNeedToDeleteMySelf(Action action) {
417 boolean expectedResult = (action== Delete);
418 MockCommand underTest = new MockCommand(InternalState.DELETE_MYSELF, Delete, Job.JobStatus.IN_PROGRESS);
419 BaseResource mockedBaseResource = mock(BaseResource.class);
420 when(underTest.getSharedData().getRequest()).thenReturn(mockedBaseResource);
421 when(mockedBaseResource.getAction()).thenReturn(action);
422 assertEquals(expectedResult, underTest.isNeedToDeleteMyself());
426 public static Object[][] testWatchingDataProvider() {
427 return new Object[][]{
428 {"all children final, no failed child ", Job.JobStatus.COMPLETED, Job.JobStatus.COMPLETED},
429 {"all children final, there is failed child ", Job.JobStatus.COMPLETED_WITH_ERRORS, Job.JobStatus.COMPLETED_WITH_ERRORS},
430 {"not all children final", Job.JobStatus.IN_PROGRESS, Job.JobStatus.IN_PROGRESS},
434 @Test(dataProvider = "testWatchingDataProvider")
435 public void testWatching(String desc, Job.JobStatus childrenJobsStatus, Job.JobStatus expectedJobStatus) {
436 MockCommand underTest = new MockCommand(InternalState.WATCHING, Delete, Job.JobStatus.IN_PROGRESS);
437 when(underTest.getWatchChildrenJobsBL().retrieveChildrenJobsStatus(any())).thenReturn(childrenJobsStatus);
438 assertEquals(expectedJobStatus, underTest.watchChildren());
442 public static Object[][] testCalcInitialStateDataProvider() {
443 return new Object[][]{
444 {Delete, true, Delete, InternalState.CREATING_CHILDREN},
445 {Delete, false, Delete, InternalState.DELETE_MYSELF},
446 {Delete, false, Create, InternalState.TERMINAL},
447 {Delete, true, Create, InternalState.CREATING_CHILDREN},
448 {Create, true, Create, InternalState.CREATE_MYSELF},
449 {Create, false, Create, InternalState.CREATE_MYSELF},
450 {Create, false, Delete, InternalState.TERMINAL},
451 {Create, true, Delete, InternalState.CREATING_CHILDREN},
452 {Create, true, Resume, InternalState.RESUME_MYSELF},
453 {Delete, false, Resume, InternalState.TERMINAL},
457 @Test(dataProvider = "testCalcInitialStateDataProvider")
458 public void testCalcInitialState(Action phase, boolean isDescendantHasAction, Action action, InternalState expectedState) {
459 ResourceCommand underTest = mock(ResourceCommand.class);
460 when(underTest.calcInitialState(any(), any())).thenCallRealMethod();
461 when(underTest.isDescendantHasAction(eq(phase))).thenReturn(isDescendantHasAction);
462 when(underTest.getActionType()).thenReturn(action);
463 when(underTest.isNeedToDeleteMyself()).thenCallRealMethod();
464 when(underTest.isNeedToCreateMyself()).thenCallRealMethod();
465 when(underTest.isNeedToResumeMySelf()).thenCallRealMethod();
467 Map<String, String> commandData = ImmutableMap.of(INTERNAL_STATE, InternalState.INITIAL.name());
468 assertEquals(expectedState, underTest.calcInitialState(commandData, phase));
472 //throw exception when call to create children
473 //create children is just example, it could be any other method that called by ResourceCommand.invokeCommand
474 public static class MockCommandThrowExceptionOnCreateChildren extends MockCommandTestingStateMachine {
476 private final RuntimeException exceptionToThrow;
478 public MockCommandThrowExceptionOnCreateChildren(RuntimeException exceptionToThrow) {
479 super(InternalState.CREATING_CHILDREN, Delete, Job.JobStatus.COMPLETED, true);
480 this.exceptionToThrow = exceptionToThrow;
481 doAnswer(returnsFirstArg()).when(this.getWatchChildrenJobsBL()).cumulateJobStatus(any(), any());
486 public Job.JobStatus createChildren() {
487 throw exceptionToThrow;
492 public static Object[][] exceptionAndStateProvider() {
493 return new Object[][]{
494 {new TryAgainException(new Exception()), Job.JobStatus.RESOURCE_IN_PROGRESS},
495 {new AbortingException(new Exception()), Job.JobStatus.FAILED},
499 @Test(dataProvider = "exceptionAndStateProvider")
500 public void whenKnownExceptionThrownInCommandInvocation_thenStateIsAsExpected(RuntimeException exception, Job.JobStatus expectedNextStatus) {
501 MockCommandTestingStateMachine underTest = new MockCommandThrowExceptionOnCreateChildren(exception);
502 NextCommand nextCommand = underTest.call();
503 assertEquals(expectedNextStatus, nextCommand.getStatus());