Changes for checkstyle 8.32
[policy/apex-pdp.git] / core / core-engine / src / test / java / org / onap / policy / apex / core / engine / executor / StateMachineExecutorTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2020 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.core.engine.executor;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.util.LinkedHashMap;
30 import java.util.Map;
31 import org.junit.After;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.mockito.Mock;
35 import org.mockito.Mockito;
36 import org.mockito.MockitoAnnotations;
37 import org.onap.policy.apex.context.parameters.SchemaParameters;
38 import org.onap.policy.apex.core.engine.ExecutorParameters;
39 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
40 import org.onap.policy.apex.core.engine.event.EnEvent;
41 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
42 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
43 import org.onap.policy.apex.model.basicmodel.service.ModelService;
44 import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
45 import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
46 import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
47 import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
48 import org.onap.policy.apex.model.eventmodel.concepts.AxField;
49 import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
50 import org.onap.policy.apex.model.policymodel.concepts.AxState;
51 import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
52 import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
53 import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
54 import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
55 import org.onap.policy.apex.model.policymodel.concepts.AxTask;
56 import org.onap.policy.apex.model.policymodel.concepts.AxTasks;
57 import org.onap.policy.common.parameters.ParameterService;
58
59 /**
60  * Test task executor.
61  */
62 public class StateMachineExecutorTest {
63     @Mock
64     private ApexInternalContext internalContextMock;
65
66     @Mock
67     private Executor<EnEvent, EnEvent, AxPolicy, ApexInternalContext> nextExecutorMock;
68
69     @Mock
70     private ExecutorFactory executorFactoryMock;
71
72     @Mock
73     private EnEvent incomingEventMock;
74
75     private AxPolicy axPolicy = new AxPolicy();
76
77     private DummyTaskSelectExecutor dummyTsle;
78
79     private DummyStateFinalizerExecutor dummySfle;
80
81     /**
82      * Set up mocking.
83      */
84     @Before
85     public void startMocking() {
86         MockitoAnnotations.initMocks(this);
87
88         axPolicy.setKey(new AxArtifactKey("Policy:0.0.1"));
89
90         AxReferenceKey state0Key = new AxReferenceKey(axPolicy.getKey(), "state0");
91         AxState state0 = new AxState(state0Key);
92
93         AxReferenceKey state1Key = new AxReferenceKey(axPolicy.getKey(), "state1");
94         AxState state1 = new AxState(state1Key);
95
96         axPolicy.getStateMap().put("State0", state0);
97         axPolicy.getStateMap().put("State1", state1);
98         axPolicy.setFirstState("state0");
99
100         AxArtifactKey event0Key = new AxArtifactKey("Event0:0.0.1");
101         AxEvent event0 = new AxEvent(event0Key, "a.name.space", "source", "target");
102         AxArtifactKey event1Key = new AxArtifactKey("Event1:0.0.1");
103         AxEvent event1 = new AxEvent(event1Key, "a.name.space", "source", "target");
104         AxArtifactKey event2Key = new AxArtifactKey("Event2:0.0.1");
105         AxEvent event2 = new AxEvent(event2Key, "a.name.space", "source", "target");
106         AxEvents events = new AxEvents();
107         events.getEventMap().put(event0Key, event0);
108         events.getEventMap().put(event1Key, event1);
109         events.getEventMap().put(event2Key, event2);
110         ModelService.registerModel(AxEvents.class, events);
111
112         AxReferenceKey fieldKey = new AxReferenceKey("Event1:0.0.1:event:Field0");
113         AxArtifactKey stringSchemaKey = new AxArtifactKey("StringSchema:0.0.1");
114         AxContextSchema stringSchema = new AxContextSchema(stringSchemaKey, "Java", "java.lang.String");
115         AxContextSchemas schemas = new AxContextSchemas();
116         schemas.getSchemasMap().put(stringSchemaKey, stringSchema);
117         ModelService.registerModel(AxContextSchemas.class, schemas);
118
119         AxField event1Field0Definition = new AxField(fieldKey, stringSchemaKey);
120         event1.getParameterMap().put("Event1Field0", event1Field0Definition);
121
122         event0.getParameterMap().put("Event1Field0", event1Field0Definition);
123         event0.getParameterMap().put("UnusedField", event1Field0Definition);
124
125         Mockito.doReturn(event0Key).when(incomingEventMock).getKey();
126         Mockito.doReturn(event0).when(incomingEventMock).getAxEvent();
127
128         state0.setTrigger(event0Key);
129         state1.setTrigger(event1Key);
130
131         AxArtifactKey task0Key = new AxArtifactKey("task0:0.0.1");
132         AxTask task0 = new AxTask(task0Key);
133
134         AxArtifactKey task1Key = new AxArtifactKey("task1:0.0.1");
135         AxTask task1 = new AxTask(task1Key);
136
137         AxTasks tasks = new AxTasks();
138         tasks.getTaskMap().put(task0Key, task0);
139         tasks.getTaskMap().put(task1Key, task1);
140         ModelService.registerModel(AxTasks.class, tasks);
141
142         ParameterService.register(new SchemaParameters());
143
144         AxReferenceKey stateOutput0Key = new AxReferenceKey("Policy:0.0.1:state0:stateOutput0");
145         AxStateOutput stateOutput0 = new AxStateOutput(stateOutput0Key, event1Key, state1.getKey());
146
147         state0.getStateOutputs().put(stateOutput0Key.getLocalName(), stateOutput0);
148
149         AxReferenceKey stateOutput1Key = new AxReferenceKey("Policy:0.0.1:state0:stateOutput1");
150         AxStateOutput stateOutput1 = new AxStateOutput(stateOutput1Key, event2Key, AxReferenceKey.getNullKey());
151
152         state1.getStateOutputs().put(stateOutput1Key.getLocalName(), stateOutput1);
153
154         AxReferenceKey str0Key = new AxReferenceKey("Policy:0.0.1:state0:str0");
155         AxStateTaskReference str0 = new AxStateTaskReference(str0Key, AxStateTaskOutputType.DIRECT, stateOutput0Key);
156         state0.getTaskReferences().put(task0Key, str0);
157
158         AxReferenceKey sflKey = new AxReferenceKey("Policy:0.0.1:state1:sfl");
159         AxStateFinalizerLogic sfl = new AxStateFinalizerLogic(sflKey, "Java", "State fianlizer logic");
160         state1.getStateFinalizerLogicMap().put("sfl", sfl);
161
162         AxReferenceKey str1Key = new AxReferenceKey("Policy:0.0.1:state1:str1");
163         AxStateTaskReference str1 = new AxStateTaskReference(str1Key, AxStateTaskOutputType.LOGIC, sflKey);
164         state1.getTaskReferences().put(task1Key, str1);
165
166         Mockito.doReturn(new DummyTaskExecutor(true)).when(executorFactoryMock).getTaskExecutor(Mockito.anyObject(),
167             Mockito.anyObject(), Mockito.anyObject());
168
169         dummyTsle = new DummyTaskSelectExecutor(true);
170         Mockito.doReturn(dummyTsle).when(executorFactoryMock).getTaskSelectionExecutor(Mockito.anyObject(),
171             Mockito.anyObject(), Mockito.anyObject());
172
173         dummySfle = new DummyStateFinalizerExecutor(true);
174         Mockito.doReturn(dummySfle).when(executorFactoryMock).getStateFinalizerExecutor(Mockito.anyObject(),
175             Mockito.anyObject(), Mockito.anyObject());
176     }
177
178     @After
179     public void cleardown() {
180         ParameterService.clear();
181         ModelService.clear();
182     }
183
184     @Test
185     public void testStateMachineExecutor() {
186         StateMachineExecutor executor =
187             new StateMachineExecutor(executorFactoryMock, new AxArtifactKey("OwnerKey:0.0.1"));
188
189         try {
190             executor.execute(0, null, incomingEventMock);
191             fail("test should throw an exception");
192         } catch (Exception ex) {
193             assertEquals("no states defined on state machine", ex.getMessage());
194         }
195
196         executor.setContext(null, axPolicy, internalContextMock);
197         assertEquals("Policy:0.0.1", executor.getKey().getId());
198         assertEquals(null, executor.getParent());
199         assertEquals(internalContextMock, executor.getContext());
200         assertEquals(null, executor.getNext());
201         assertEquals(null, executor.getIncoming());
202         assertEquals(null, executor.getOutgoing());
203         assertEquals(axPolicy, executor.getSubject());
204
205         executor.setParameters(new ExecutorParameters());
206         executor.setNext(nextExecutorMock);
207         assertEquals(nextExecutorMock, executor.getNext());
208         executor.setNext(null);
209         assertEquals(null, executor.getNext());
210
211         try {
212             executor.executePre(0, null, null);
213             fail("test should throw an exception");
214         } catch (Exception ex) {
215             assertEquals("execution pre work not implemented on class", ex.getMessage());
216         }
217
218         try {
219             executor.executePost(false);
220             fail("test should throw an exception");
221         } catch (Exception ex) {
222             assertEquals("execution post work not implemented on class", ex.getMessage());
223         }
224
225         try {
226             executor.prepare();
227             fail("test should throw an exception");
228         } catch (Exception e) {
229             assertTrue(e instanceof NullPointerException);
230         }
231
232         axPolicy.setFirstState("BadState");
233         executor.setContext(null, axPolicy, internalContextMock);
234         try {
235             executor.execute(0, null, incomingEventMock);
236             fail("test should throw an exception");
237         } catch (Exception ex) {
238             assertEquals("first state not defined on state machine", ex.getMessage());
239         }
240
241         axPolicy.setFirstState("state0");
242         executor.setContext(null, axPolicy, internalContextMock);
243         try {
244             executor.execute(0, null, incomingEventMock);
245         } catch (Exception ex) {
246             fail("test should not throw an exception");
247         }
248
249         dummyTsle.setTaskNo(0);
250         try {
251             executor.execute(0, null, incomingEventMock);
252         } catch (Exception ex) {
253             fail("test should not throw an exception");
254         }
255
256         AxReferenceKey badStateKey = new AxReferenceKey("Policy:0.0.1:PName:BadState");
257         axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1").setNextState(badStateKey);
258         dummyTsle.setTaskNo(0);
259         try {
260             executor.execute(0, null, incomingEventMock);
261             fail("test should throw an exception");
262         } catch (Exception ex) {
263             assertEquals("state execution failed, next state \"Policy:0.0.1:PName:BadState\" not found",
264                 ex.getMessage());
265         }
266
267         axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1")
268             .setNextState(AxReferenceKey.getNullKey());
269         dummyTsle.setTaskNo(0);
270         try {
271             executor.execute(0, null, incomingEventMock);
272         } catch (Exception ex) {
273             fail("test should not throw an exception");
274         }
275
276         axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("BadTrigger:0.0.1"));
277         dummyTsle.setTaskNo(0);
278         try {
279             executor.execute(0, null, incomingEventMock);
280             fail("test should throw an exception");
281         } catch (Exception ex) {
282             assertEquals("incoming event \"Event1:0.0.1\" does not match trigger \"BadTrigger:0.0.1\" "
283                 + "of state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
284         }
285
286         axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("Event1:0.0.1"));
287         dummyTsle.setTaskNo(0);
288         try {
289             executor.execute(0, null, incomingEventMock);
290         } catch (Exception ex) {
291             fail("test should not throw an exception");
292         }
293
294         AxStateFinalizerLogic savedSfl = axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().get("sfl");
295         axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", null);
296         try {
297             executor.setContext(null, axPolicy, internalContextMock);
298             fail("test should throw an exception");
299         } catch (Exception ex) {
300             assertEquals("state finalizer logic on task reference "
301                 + "\"AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=Policy,"
302                 + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1),"
303                 + "outputType=LOGIC,output=AxReferenceKey:(parentKeyName=Policy,parentKeyVersion=0.0.1,"
304                 + "parentLocalName=state1,localName=sfl))\" on state \"Policy:0.0.1:NULL:state1\" " + "does not exist",
305                 ex.getMessage());
306         }
307
308         axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", savedSfl);
309         executor.setContext(null, axPolicy, internalContextMock);
310
311         dummyTsle.setTaskNo(0);
312         try {
313             executor.execute(0, null, incomingEventMock);
314         } catch (Exception ex) {
315             fail("test should not throw an exception");
316         }
317
318         AxArtifactKey task1Key = new AxArtifactKey("task1:0.0.1");
319         try {
320             axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key)
321                 .setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
322             executor.setContext(null, axPolicy, internalContextMock);
323             fail("test should throw an exception");
324         } catch (Exception ex) {
325             assertEquals("invalid state output type on task reference \"AxStateTaskReference:(stateKey=AxReferenceKey:"
326                 + "(parentKeyName=Policy,parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1),"
327                 + "outputType=UNDEFINED,output=AxReferenceKey:(parentKeyName=Policy,"
328                 + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=sfl))\" "
329                 + "on state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
330         }
331
332         axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key)
333             .setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
334         executor.setContext(null, axPolicy, internalContextMock);
335
336         dummyTsle.setTaskNo(0);
337         try {
338             executor.execute(0, null, incomingEventMock);
339         } catch (Exception ex) {
340             fail("test should not throw an exception");
341         }
342
343         dummyTsle.setTaskNo(0);
344         dummySfle.setReturnBad(true);
345         try {
346             executor.execute(0, null, incomingEventMock);
347             fail("test should throw an exception");
348         } catch (Exception ex) {
349             assertEquals("State execution of state \"Policy:0.0.1:NULL:state1\" on task \"task1:0.0.1\" failed: "
350                 + "state output definition for state output \"stateOutputBad\" not found for "
351                 + "state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
352         }
353
354         dummyTsle.setTaskNo(0);
355         dummySfle.setReturnBad(false);
356         try {
357             executor.execute(0, null, incomingEventMock);
358         } catch (Exception ex) {
359             fail("test should not throw an exception");
360         }
361
362         try {
363             executor.cleanUp();
364             fail("test should throw an exception");
365         } catch (Exception ex) {
366             assertEquals("cleanUp() not implemented on class", ex.getMessage());
367         }
368     }
369
370     @Test
371     public void testStateOutput() {
372         StateOutput output =
373             new StateOutput(axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0"));
374         assertNotNull(output);
375
376         assertEquals("stateOutput0", output.getStateOutputDefinition().getKey().getLocalName());
377
378         try {
379             output.setEventFields(null, null);
380             fail("test should throw an exception");
381         } catch (Exception ex) {
382             assertEquals("incomingFieldDefinitionMap may not be null", ex.getMessage());
383         }
384
385         Map<String, AxField> incomingFieldDefinitionMap = new LinkedHashMap<>();
386         try {
387             output.setEventFields(incomingFieldDefinitionMap, null);
388             fail("test should throw an exception");
389         } catch (Exception ex) {
390             assertEquals("eventFieldMap may not be null", ex.getMessage());
391         }
392
393         Map<String, Object> eventFieldMap = new LinkedHashMap<>();
394         try {
395             output.setEventFields(incomingFieldDefinitionMap, eventFieldMap);
396         } catch (Exception ex) {
397             fail("test should not throw an exception");
398         }
399
400         eventFieldMap.put("key", "Value");
401         try {
402             output.setEventFields(incomingFieldDefinitionMap, eventFieldMap);
403             fail("test should throw an exception");
404         } catch (Exception ex) {
405             assertEquals("field definitions and values do not match for event Event1:0.0.1\n[]\n[key]",
406                 ex.getMessage());
407         }
408
409         AxField axBadFieldDefinition = new AxField();
410         incomingFieldDefinitionMap.put("key", axBadFieldDefinition);
411         try {
412             output.setEventFields(incomingFieldDefinitionMap, eventFieldMap);
413             fail("test should throw an exception");
414         } catch (Exception ex) {
415             assertEquals("field \"key\" does not exist on event \"Event1:0.0.1\"", ex.getMessage());
416         }
417
418         incomingFieldDefinitionMap.clear();
419         eventFieldMap.clear();
420         AxArtifactKey stringSchemaKey = new AxArtifactKey("StringSchema:0.0.1");
421         AxReferenceKey fieldKey = new AxReferenceKey("Event1:0.0.1:event:Field0");
422         AxField event1Field0Definition = new AxField(fieldKey, stringSchemaKey);
423         incomingFieldDefinitionMap.put("Event1Field0", event1Field0Definition);
424         eventFieldMap.put("Event1Field0", "Value");
425         try {
426             output.setEventFields(incomingFieldDefinitionMap, eventFieldMap);
427         } catch (Exception ex) {
428             fail("test should not throw an exception");
429         }
430
431         output = new StateOutput(axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0"));
432
433         EnEvent incomingEvent = new EnEvent(new AxArtifactKey("Event0:0.0.1"));
434         output.copyUnsetFields(incomingEvent);
435
436         incomingEvent.put("Event1Field0", "Hello");
437         output.copyUnsetFields(incomingEvent);
438     }
439 }