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.ImmutableMap;
24 import org.jetbrains.annotations.NotNull;
25 import org.onap.vid.exceptions.GenericUncheckedException;
26 import org.onap.vid.job.Job;
27 import org.onap.vid.job.JobAdapter;
28 import org.onap.vid.job.NextCommand;
29 import org.onap.vid.job.impl.JobSharedData;
30 import org.onap.vid.model.Action;
31 import org.onap.vid.model.serviceInstantiation.BaseResource;
32 import org.onap.vid.mso.RestMsoImplementation;
33 import org.springframework.http.HttpMethod;
34 import org.testng.annotations.DataProvider;
35 import org.testng.annotations.Test;
37 import javax.ws.rs.ProcessingException;
38 import java.util.Collections;
39 import java.util.Optional;
40 import java.util.stream.Stream;
42 import static org.mockito.ArgumentMatchers.any;
43 import static org.mockito.Mockito.*;
44 import static org.onap.vid.job.command.ResourceCommandKt.ACTION_PHASE;
45 import static org.onap.vid.job.command.ResourceCommandKt.INTERNAL_STATE;
46 import static org.onap.vid.utils.Logging.getMethodCallerName;
47 import static org.testng.Assert.assertNull;
48 import static org.testng.Assert.assertTrue;
49 import static org.testng.AssertJUnit.assertEquals;
50 import static org.testng.AssertJUnit.assertFalse;
52 public class ResourceCommandTest {
54 public static class MockCommand extends ResourceCommand {
56 public MockCommand(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus) {
57 super(mock(RestMsoImplementation.class, RETURNS_MOCKS), mock(InProgressStatusService.class), mock(MsoResultHandlerService.class, RETURNS_MOCKS), mock(WatchChildrenJobsBL.class));
59 this.mockedJobStatus = mockedJobStatus;
60 this.mockState = mockState;
61 this.mockPhase = mockPhase;
62 if (mockState==InternalState.INITIAL) {
63 init(mock(JobSharedData.class), Collections.emptyMap());
66 init(mock(JobSharedData.class), ImmutableMap.of(INTERNAL_STATE, mockState.name(), ACTION_PHASE, mockPhase.name()));
68 when(this.getWatchChildrenJobsBL().cumulateJobStatus(any(), any())).thenReturn(mockedJobStatus);
71 private final Job.JobStatus mockedJobStatus;
72 private final InternalState mockState;
73 private final Action mockPhase;
78 public Job.JobStatus createChildren() {
79 if (mockState == InternalState.CREATING_CHILDREN || (mockState == InternalState.INITIAL && mockPhase== Action.Delete))
80 return mockedJobStatus;
81 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
84 protected Job.JobStatus mockedStatusOrThrow(InternalState expectedState) {
85 if (mockState == expectedState)
86 return mockedJobStatus;
87 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
90 protected MsoRestCallPlan mockedPlanOrThrow(InternalState expectedState) {
91 if (mockState == expectedState)
92 return new MsoRestCallPlan(HttpMethod.POST, "path", Optional.empty(), Optional.empty(), "nothing");
93 throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
98 public MsoRestCallPlan planCreateMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) {
99 return mockedPlanOrThrow(InternalState.CREATE_MYSELF);
104 public MsoRestCallPlan planDeleteMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) {
105 return mockedPlanOrThrow(InternalState.DELETE_MYSELF);
109 public static class MockCommandTestingStateMachine extends MockCommand {
111 private final JobSharedData sharedData;
113 public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf) {
114 this(mockState, mockPhase, mockedJobStatus, mockedNeedToDeleteMySelf, false);
117 public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf, boolean isService) {
118 super(mockState, mockPhase, mockedJobStatus);
119 this.mockedNeedToDeleteMySelf = mockedNeedToDeleteMySelf;
120 this.isService = isService;
121 this.sharedData = mock(JobSharedData.class, RETURNS_MOCKS);
124 protected final boolean mockedNeedToDeleteMySelf;
125 private final boolean isService;
129 public Job.JobStatus inProgress() {
130 return mockedStatusOrThrow(InternalState.IN_PROGRESS);
135 public Job.JobStatus watchChildren() {
136 return mockedStatusOrThrow(InternalState.WATCHING);
140 public boolean isNeedToDeleteMyself() {
141 return mockedNeedToDeleteMySelf;
145 protected boolean isServiceCommand() {
150 public JobSharedData getSharedData() {
156 public static Object[][] nextStateDeletePhaseProvider() {
157 return new Object[][]{
158 {InternalState.CREATING_CHILDREN, Job.JobStatus.COMPLETED, InternalState.WATCHING},
159 {InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF},
160 {InternalState.WATCHING, Job.JobStatus.IN_PROGRESS, InternalState.WATCHING},
161 {InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING},
162 {InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS},
163 {InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, InternalState.TERMINAL},
164 {InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS},
165 {InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.IN_PROGRESS},
169 @Test(dataProvider = "nextStateDeletePhaseProvider")
170 public void whenCalcNextStateDeletePhase_expectedStateIsReturned(
171 InternalState internalState, Job.JobStatus jobStatus, InternalState expectedState) {
173 //there is no meaning to the constructor inputs here
174 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Action.Delete, Job.JobStatus.FAILED, true);
175 assertEquals(expectedState, underTest.calcNextStateDeletePhase(jobStatus, internalState));
179 public void whenNoNeedToDeleteMyself_internalStateMovesFromWatchingToTerminal() {
180 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Action.Delete, Job.JobStatus.COMPLETED, false);
181 assertEquals(InternalState.TERMINAL, underTest.calcNextStateDeletePhase(Job.JobStatus.COMPLETED, InternalState.WATCHING));
185 public static Object[][] testShallStopJobDataProvider() {
186 return new Object[][]{
187 {Job.JobStatus.IN_PROGRESS, Action.None, false, false},
188 {Job.JobStatus.COMPLETED_WITH_NO_ACTION, Action.None, false, false},
189 {Job.JobStatus.COMPLETED, Action.None, false, false},
190 {Job.JobStatus.FAILED, Action.None, false, true},
191 {Job.JobStatus.COMPLETED_WITH_ERRORS, Action.None, false, true},
192 {Job.JobStatus.COMPLETED_WITH_ERRORS, Action.None, true, false},
193 {Job.JobStatus.FAILED, Action.None, true, false},
194 {Job.JobStatus.FAILED, Action.Delete, true, true},
195 {Job.JobStatus.FAILED, Action.Create, true, true},
200 @Test(dataProvider = "testShallStopJobDataProvider")
201 public void testShallStopJob(Job.JobStatus jobStatus, Action action, boolean isService, boolean expectedResult) {
202 //in this test, there is no meaning to constructor parameters besides isService
203 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Action.Delete, Job.JobStatus.COMPLETED, false, isService);
205 BaseResource mockedRequest = mock(BaseResource.class);
206 when(underTest.getSharedData().getRequest()).thenReturn(mockedRequest);
207 when(mockedRequest.getAction()).thenReturn(action);
209 assertEquals(expectedResult, underTest.shallStopJob(jobStatus));
213 public static Object[][] testCallDataProvider() {
214 return new Object[][]{
215 {"initial state with successful creating children" ,InternalState.INITIAL, Job.JobStatus.COMPLETED, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
216 {"initial state with failed creating children", InternalState.INITIAL, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
217 {"watching state with children still in progress" ,InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
218 {"watching state with children that completed with errors" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_ERRORS, null, Job.JobStatus.COMPLETED_WITH_ERRORS},
219 {"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},
220 {"watching state with children that has completed" ,InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS},
221 {"mso call state that failed" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
222 //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},
223 {"mso call state that success" ,InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
224 {"in progress return in progress" ,InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
225 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.PAUSE, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
226 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.STOPPED, null, Job.JobStatus.STOPPED},
227 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
228 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, null, Job.JobStatus.COMPLETED},
233 @Test(dataProvider = "testCallDataProvider")
234 public void whenCallCommandWithDeletePhase_nextJobStatusAndInternalStateAreAsExpected(
235 String description, InternalState internalState, Job.JobStatus currentStateResult,
236 InternalState expectedNextState, Job.JobStatus expectedNextStatus) {
238 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(internalState, Action.Delete, currentStateResult, true);
239 NextCommand nextCommand = underTest.call();
240 assertEquals(expectedNextStatus, nextCommand.getStatus());
242 //expectedNextState == null means nextCommand has no real command
243 if (expectedNextState!=null) {
244 assertEquals(expectedNextState, (nextCommand.getCommand().getData().get(INTERNAL_STATE)));
245 assertFalse(nextCommand.getStatus().isFinal());
248 assertNull(nextCommand.getCommand());
249 assertTrue(nextCommand.getStatus().isFinal());
253 @Test(expectedExceptions = IllegalStateException.class)
254 public void whenCommandInUnMappedState_exceptionIsThrown() {
255 MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Action.Delete, Job.JobStatus.COMPLETED, true);
260 public static Object[][] InProgressDataProvider() {
261 return Stream.of(Job.JobStatus.values())
262 .map(status -> new Object[] { status })
263 .toArray(Object[][]::new);
266 @Test(dataProvider = "InProgressDataProvider")
267 public void whenGetResultFromMso_InProgressReturnThem(Job.JobStatus mockedJobStatus) {
268 Job.JobStatus expectedJobStatus = (mockedJobStatus== Job.JobStatus.PAUSE) ? Job.JobStatus.IN_PROGRESS : mockedJobStatus;
269 MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Action.Delete, mockedJobStatus);
270 when(underTest.getInProgressStatusService().call(any(), any(), any())).thenReturn(mockedJobStatus);
271 assertEquals(expectedJobStatus, underTest.inProgress());
275 public static Object[][] InProgressExceptionsDataProvider() {
276 return new Object[][]{
277 {new ProcessingException(""), Job.JobStatus.IN_PROGRESS},
278 {new InProgressStatusService.BadResponseFromMso(null), Job.JobStatus.IN_PROGRESS},
279 {new GenericUncheckedException(""),Job.JobStatus.STOPPED }
283 @Test(dataProvider = "InProgressExceptionsDataProvider")
284 public void whenInProgressStatusServiceThrowException_InProgressReturnStatus(Exception exception, Job.JobStatus expectedJobStatus) {
285 MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Action.Delete, expectedJobStatus);
286 when(underTest.getInProgressStatusService().call(any(), any(), any())).thenThrow(exception);
287 assertEquals(expectedJobStatus, underTest.inProgress());
291 public static Object[][] testIsNeedToDeleteMySelfDataProvider() {
292 return Stream.of(Action.values())
293 .map(status -> new Object[] { status })
294 .toArray(Object[][]::new);
297 @Test(dataProvider = "testIsNeedToDeleteMySelfDataProvider")
298 public void testIsNeedToDeleteMySelf(Action action) {
299 boolean expectedResult = (action== Action.Delete);
300 MockCommand underTest = new MockCommand(InternalState.DELETE_MYSELF, Action.Delete, Job.JobStatus.IN_PROGRESS);
301 BaseResource mockedBaseResource = mock(BaseResource.class);
302 when(underTest.getSharedData().getRequest()).thenReturn(mockedBaseResource);
303 when(mockedBaseResource.getAction()).thenReturn(action);
304 assertEquals(expectedResult, underTest.isNeedToDeleteMyself());
308 public static Object[][] testWatchingDataProvider() {
309 return new Object[][]{
310 {"all children final, no failed child ", Job.JobStatus.COMPLETED, Job.JobStatus.COMPLETED},
311 {"all children final, there is failed child ", Job.JobStatus.COMPLETED_WITH_ERRORS, Job.JobStatus.COMPLETED_WITH_ERRORS},
312 {"not all children final", Job.JobStatus.IN_PROGRESS, Job.JobStatus.IN_PROGRESS},
316 @Test(dataProvider = "testWatchingDataProvider")
317 public void testWatching(String desc, Job.JobStatus childrenJobsStatus, Job.JobStatus expectedJobStatus) {
318 MockCommand underTest = new MockCommand(InternalState.WATCHING, Action.Delete, Job.JobStatus.IN_PROGRESS);
319 when(underTest.getWatchChildrenJobsBL().retrieveChildrenJobsStatus(any())).thenReturn(childrenJobsStatus);
320 assertEquals(expectedJobStatus, underTest.watchChildren());