Merge from ECOMP's repository
[vid.git] / vid-app-common / src / test / java / org / onap / vid / job / command / ResourceCommandTest.java
1 package org.onap.vid.job.command;
2
3 import com.google.common.collect.ImmutableMap;
4 import org.jetbrains.annotations.NotNull;
5 import org.onap.vid.exceptions.GenericUncheckedException;
6 import org.onap.vid.job.Job;
7 import org.onap.vid.job.JobAdapter;
8 import org.onap.vid.job.NextCommand;
9 import org.onap.vid.job.impl.JobSharedData;
10 import org.onap.vid.model.Action;
11 import org.onap.vid.model.serviceInstantiation.BaseResource;
12 import org.onap.vid.mso.RestMsoImplementation;
13 import org.springframework.http.HttpMethod;
14 import org.testng.annotations.DataProvider;
15 import org.testng.annotations.Test;
16
17 import javax.ws.rs.ProcessingException;
18 import java.util.Collections;
19 import java.util.Optional;
20 import java.util.stream.Stream;
21
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.Mockito.*;
24 import static org.onap.vid.job.command.ResourceCommandKt.ACTION_PHASE;
25 import static org.onap.vid.job.command.ResourceCommandKt.INTERNAL_STATE;
26 import static org.onap.vid.utils.Logging.getMethodCallerName;
27 import static org.testng.Assert.assertNull;
28 import static org.testng.Assert.assertTrue;
29 import static org.testng.AssertJUnit.assertEquals;
30 import static org.testng.AssertJUnit.assertFalse;
31
32 public class ResourceCommandTest {
33
34     public static class MockCommand extends ResourceCommand {
35
36         public MockCommand(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus) {
37             super(mock(RestMsoImplementation.class, RETURNS_MOCKS), mock(InProgressStatusService.class), mock(MsoResultHandlerService.class, RETURNS_MOCKS), mock(WatchChildrenJobsBL.class));
38
39             this.mockedJobStatus = mockedJobStatus;
40             this.mockState = mockState;
41             this.mockPhase = mockPhase;
42             if (mockState==InternalState.INITIAL) {
43                 init(mock(JobSharedData.class), Collections.emptyMap());
44             }
45             else {
46                 init(mock(JobSharedData.class), ImmutableMap.of(INTERNAL_STATE, mockState.name(), ACTION_PHASE, mockPhase.name()));
47             }
48             when(this.getWatchChildrenJobsBL().cumulateJobStatus(any(), any())).thenReturn(mockedJobStatus);
49         }
50
51         private final Job.JobStatus mockedJobStatus;
52         private final InternalState mockState;
53         private final Action mockPhase;
54
55
56         @NotNull
57         @Override
58         public Job.JobStatus createChildren() {
59             if (mockState == InternalState.CREATING_CHILDREN || (mockState == InternalState.INITIAL && mockPhase== Action.Delete))
60                 return mockedJobStatus;
61             throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
62         }
63
64         protected Job.JobStatus mockedStatusOrThrow(InternalState expectedState) {
65             if (mockState == expectedState)
66                 return mockedJobStatus;
67             throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
68         }
69
70         protected MsoRestCallPlan mockedPlanOrThrow(InternalState expectedState) {
71             if (mockState == expectedState)
72                 return new MsoRestCallPlan(HttpMethod.POST, "path", Optional.empty(), Optional.empty(), "nothing");
73             throw (new RuntimeException("Not expected to call "+getMethodCallerName()));
74         }
75
76         @NotNull
77         @Override
78         public MsoRestCallPlan planCreateMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) {
79             return mockedPlanOrThrow(InternalState.CREATE_MYSELF);
80         }
81
82         @NotNull
83         @Override
84         public MsoRestCallPlan planDeleteMyselfRestCall(@NotNull CommandParentData commandParentData, @NotNull JobAdapter.AsyncJobRequest request, @NotNull String userId) {
85             return mockedPlanOrThrow(InternalState.DELETE_MYSELF);
86         }
87     }
88
89     public static class MockCommandTestingStateMachine extends MockCommand {
90
91         private final JobSharedData sharedData;
92
93         public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf) {
94             this(mockState, mockPhase, mockedJobStatus, mockedNeedToDeleteMySelf, false);
95         }
96
97         public MockCommandTestingStateMachine(InternalState mockState, Action mockPhase, Job.JobStatus mockedJobStatus, boolean mockedNeedToDeleteMySelf, boolean isService) {
98             super(mockState, mockPhase, mockedJobStatus);
99             this.mockedNeedToDeleteMySelf = mockedNeedToDeleteMySelf;
100             this.isService = isService;
101             this.sharedData = mock(JobSharedData.class, RETURNS_MOCKS);
102         }
103
104         protected final boolean mockedNeedToDeleteMySelf;
105         private final boolean isService;
106
107         @NotNull
108         @Override
109         public Job.JobStatus inProgress() {
110             return mockedStatusOrThrow(InternalState.IN_PROGRESS);
111         }
112
113         @NotNull
114         @Override
115         public Job.JobStatus watchChildren() {
116             return mockedStatusOrThrow(InternalState.WATCHING);
117         }
118
119         @Override
120         public boolean isNeedToDeleteMyself() {
121             return mockedNeedToDeleteMySelf;
122         }
123
124         @Override
125         protected boolean isServiceCommand() {
126             return isService;
127         }
128
129         @Override
130         public JobSharedData getSharedData() {
131             return sharedData;
132         }
133     }
134
135     @DataProvider
136     public static Object[][] nextStateDeletePhaseProvider() {
137         return new Object[][]{
138                 {InternalState.CREATING_CHILDREN, Job.JobStatus.COMPLETED, InternalState.WATCHING},
139                 {InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF},
140                 {InternalState.WATCHING, Job.JobStatus.IN_PROGRESS, InternalState.WATCHING},
141                 {InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING},
142                 {InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS},
143                 {InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, InternalState.TERMINAL},
144                 {InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS},
145                 {InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.IN_PROGRESS},
146         };
147     }
148
149     @Test(dataProvider = "nextStateDeletePhaseProvider")
150     public void whenCalcNextStateDeletePhase_expectedStateIsReturned(
151             InternalState internalState, Job.JobStatus jobStatus, InternalState expectedState) {
152
153         //there is no meaning to the constructor inputs here
154         MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Action.Delete, Job.JobStatus.FAILED, true);
155         assertEquals(expectedState, underTest.calcNextStateDeletePhase(jobStatus, internalState));
156     }
157
158     @Test
159     public void whenNoNeedToDeleteMyself_internalStateMovesFromWatchingToTerminal() {
160         MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Action.Delete, Job.JobStatus.COMPLETED, false);
161         assertEquals(InternalState.TERMINAL, underTest.calcNextStateDeletePhase(Job.JobStatus.COMPLETED, InternalState.WATCHING));
162     }
163
164     @DataProvider
165     public static Object[][] testShallStopJobDataProvider() {
166         return new Object[][]{
167                 {Job.JobStatus.IN_PROGRESS, Action.None, false, false},
168                 {Job.JobStatus.COMPLETED_WITH_NO_ACTION, Action.None, false, false},
169                 {Job.JobStatus.COMPLETED, Action.None, false, false},
170                 {Job.JobStatus.FAILED, Action.None, false, true},
171                 {Job.JobStatus.COMPLETED_WITH_ERRORS, Action.None, false, true},
172                 {Job.JobStatus.COMPLETED_WITH_ERRORS, Action.None, true, false},
173                 {Job.JobStatus.FAILED, Action.None, true, false},
174                 {Job.JobStatus.FAILED, Action.Delete, true, true},
175                 {Job.JobStatus.FAILED, Action.Create, true, true},
176         };
177     }
178
179
180     @Test(dataProvider = "testShallStopJobDataProvider")
181     public void testShallStopJob(Job.JobStatus jobStatus, Action action, boolean isService, boolean expectedResult) {
182         //in this test, there is no meaning to constructor parameters besides isService
183         MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.WATCHING, Action.Delete, Job.JobStatus.COMPLETED, false, isService);
184
185         BaseResource mockedRequest = mock(BaseResource.class);
186         when(underTest.getSharedData().getRequest()).thenReturn(mockedRequest);
187         when(mockedRequest.getAction()).thenReturn(action);
188
189         assertEquals(expectedResult, underTest.shallStopJob(jobStatus));
190     }
191
192     @DataProvider
193     public static Object[][] testCallDataProvider() {
194         return new Object[][]{
195                 {"initial state with successful creating children" ,InternalState.INITIAL, Job.JobStatus.COMPLETED, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
196                 {"initial state with failed creating children", InternalState.INITIAL, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
197                 {"watching state with children still in progress" ,InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS, InternalState.WATCHING, Job.JobStatus.RESOURCE_IN_PROGRESS},
198                 {"watching state with children that completed with errors" ,InternalState.WATCHING, Job.JobStatus.COMPLETED_WITH_ERRORS, null, Job.JobStatus.COMPLETED_WITH_ERRORS},
199                 {"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},
200                 {"watching state with children that has completed" ,InternalState.WATCHING, Job.JobStatus.COMPLETED, InternalState.DELETE_MYSELF, Job.JobStatus.RESOURCE_IN_PROGRESS},
201                 {"mso call state that failed" ,InternalState.DELETE_MYSELF, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
202                 //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},
203                 {"mso call state that success" ,InternalState.DELETE_MYSELF, Job.JobStatus.COMPLETED, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
204                 {"in progress return in progress" ,InternalState.IN_PROGRESS, Job.JobStatus.IN_PROGRESS, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
205                 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.PAUSE, InternalState.IN_PROGRESS, Job.JobStatus.RESOURCE_IN_PROGRESS},
206                 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.STOPPED, null, Job.JobStatus.STOPPED},
207                 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.FAILED, null, Job.JobStatus.FAILED},
208                 {"in progress return in pause" ,InternalState.IN_PROGRESS, Job.JobStatus.COMPLETED, null, Job.JobStatus.COMPLETED},
209
210         };
211     }
212
213     @Test(dataProvider = "testCallDataProvider")
214     public void whenCallCommandWithDeletePhase_nextJobStatusAndInternalStateAreAsExpected(
215             String description, InternalState internalState, Job.JobStatus currentStateResult,
216             InternalState expectedNextState, Job.JobStatus expectedNextStatus) {
217
218         MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(internalState, Action.Delete, currentStateResult, true);
219         NextCommand nextCommand = underTest.call();
220         assertEquals(expectedNextStatus, nextCommand.getStatus());
221
222         //expectedNextState == null means nextCommand has no real command
223         if (expectedNextState!=null) {
224             assertEquals(expectedNextState, (nextCommand.getCommand().getData().get(INTERNAL_STATE)));
225             assertFalse(nextCommand.getStatus().isFinal());
226         }
227         else {
228             assertNull(nextCommand.getCommand());
229             assertTrue(nextCommand.getStatus().isFinal());
230         }
231     }
232
233     @Test(expectedExceptions = IllegalStateException.class)
234     public void whenCommandInUnMappedState_exceptionIsThrown() {
235         MockCommandTestingStateMachine underTest = new MockCommandTestingStateMachine(InternalState.TERMINAL, Action.Delete, Job.JobStatus.COMPLETED, true);
236         underTest.call();
237     }
238
239     @DataProvider
240     public static Object[][] InProgressDataProvider() {
241         return Stream.of(Job.JobStatus.values())
242                 .map(status -> new Object[] { status })
243                 .toArray(Object[][]::new);
244     }
245
246     @Test(dataProvider = "InProgressDataProvider")
247     public void whenGetResultFromMso_InProgressReturnThem(Job.JobStatus mockedJobStatus) {
248         Job.JobStatus expectedJobStatus = (mockedJobStatus== Job.JobStatus.PAUSE) ? Job.JobStatus.IN_PROGRESS : mockedJobStatus;
249         MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Action.Delete, mockedJobStatus);
250         when(underTest.getInProgressStatusService().call(any(), any(), any())).thenReturn(mockedJobStatus);
251         assertEquals(expectedJobStatus, underTest.inProgress());
252     }
253
254     @DataProvider
255     public static Object[][] InProgressExceptionsDataProvider() {
256         return new Object[][]{
257                 {new ProcessingException(""), Job.JobStatus.IN_PROGRESS},
258                 {new InProgressStatusService.BadResponseFromMso(null), Job.JobStatus.IN_PROGRESS},
259                 {new GenericUncheckedException(""),Job.JobStatus.STOPPED }
260         };
261     }
262
263     @Test(dataProvider = "InProgressExceptionsDataProvider")
264     public void whenInProgressStatusServiceThrowException_InProgressReturnStatus(Exception exception, Job.JobStatus expectedJobStatus) {
265         MockCommand underTest = new MockCommand(InternalState.IN_PROGRESS, Action.Delete, expectedJobStatus);
266         when(underTest.getInProgressStatusService().call(any(), any(), any())).thenThrow(exception);
267         assertEquals(expectedJobStatus, underTest.inProgress());
268     }
269
270     @DataProvider
271     public static Object[][] testIsNeedToDeleteMySelfDataProvider() {
272         return Stream.of(Action.values())
273                 .map(status -> new Object[] { status })
274                 .toArray(Object[][]::new);
275     }
276
277     @Test(dataProvider = "testIsNeedToDeleteMySelfDataProvider")
278     public void testIsNeedToDeleteMySelf(Action action) {
279         boolean expectedResult = (action== Action.Delete);
280         MockCommand underTest = new MockCommand(InternalState.DELETE_MYSELF, Action.Delete, Job.JobStatus.IN_PROGRESS);
281         BaseResource mockedBaseResource = mock(BaseResource.class);
282         when(underTest.getSharedData().getRequest()).thenReturn(mockedBaseResource);
283         when(mockedBaseResource.getAction()).thenReturn(action);
284         assertEquals(expectedResult, underTest.isNeedToDeleteMyself());
285     }
286
287     @DataProvider
288     public static Object[][] testWatchingDataProvider() {
289         return new Object[][]{
290                 {"all children final, no failed child ", Job.JobStatus.COMPLETED, Job.JobStatus.COMPLETED},
291                 {"all children final, there is failed child ", Job.JobStatus.COMPLETED_WITH_ERRORS, Job.JobStatus.COMPLETED_WITH_ERRORS},
292                 {"not all children final", Job.JobStatus.IN_PROGRESS, Job.JobStatus.IN_PROGRESS},
293         };
294     }
295
296     @Test(dataProvider = "testWatchingDataProvider")
297     public void testWatching(String desc, Job.JobStatus childrenJobsStatus, Job.JobStatus expectedJobStatus) {
298         MockCommand underTest = new MockCommand(InternalState.WATCHING, Action.Delete, Job.JobStatus.IN_PROGRESS);
299         when(underTest.getWatchChildrenJobsBL().retrieveChildrenJobsStatus(any())).thenReturn(childrenJobsStatus);
300         assertEquals(expectedJobStatus, underTest.watchChildren());
301     }
302
303 }